Trying to comment on a photo in Laravel - php

Hello I am learning Laravel and I have an image gallery and I want to be able to comment on each photo
This is my comments table:
public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('user_id')->index();
$table->unsignedinteger('photo_id')->index();
$table->text('body',190);
$table->timestamps();
});
}
This is my photos table:
public function up()
{
Schema::create('photos', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('user_id')->index();
$table->string('title');
$table->string('image');
$table->timestamps();
});
}
this is the photos model:
protected $fillable = [
'user_id','title','image'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
and this is the comment model:
protected $fillable = ['user_id','photo_id','body'];
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
public function photo()
{
return $this->belongsTo(Photo::class,'photo_id');
}
And this is my controller:
public function index()
{
// dd('here');
$images = Photos::find($id);
return View::make('detail')->with('images', $images);
// return View::make('detail',compact($images,$comment));
// $comment = Comment::all();
// return view('detail',compact('comments'));
// return view('detail');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function update(Request $request,$id)
{
// dd('test');
$this->validate($request, [
'photo_id' => 'required|exists:photos,id',
'body' => 'required',
]);
$comment= Comment::create([
'user_id'=>auth()->id(),
'photo_id'=>request('photo_id'),
'body'=>request('body')
]);
return back();
}
/**
* Display the specified resource.
*
* #param \App\Comment $comment
* #return \Illuminate\Http\Response
*/
public function show(Comment $comment)
{
$comments = Comment::all();
return view('detail',compact('comments'));
}
I am trying to make the controller work but it is not correct because I still do not understand Eloquent relationships fully. Please help me.

Your tables and models are correct, you just need to find your photo by id then save it like this
$photo = Photo::find($id);
$photo->comments()->create([
'user_id'=>auth()->id(),
'body'=>request('body')
]);
or even you can do it inline
Photo::find($id)->comments()->create([
'user_id'=>auth()->id(),
'body'=>request('body')
]);

Related

Laravel-8 one-many/many-one relationship

I'm trying to display category for each entry's page, but they all only display 'JavaScript.'
(A category can have many entries, but each entry has exactly one category.)
My Category model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $table = 'categories';
protected $fillable = [
'name'
];
public function entries() {
return $this->hasMany(Entry::class);
}
}
My Entry model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Entry extends Model
{
protected $table = 'entries';
protected $fillable = [
'title',
'hours',
'minutes',
'category_id',
'difficulty',
'url'
];
public function categories() {
return $this->belongsTo(Category::class, 'category_id');
}
public function getCreatedAtAttribute($value)
{
return date('F d, Y H:i', strtotime($value));
}
}
My EntryController's show() method:
/**
* Display the specified resource.
*
* #param Entry $entry
* #return \Illuminate\Http\Response
*/
public function show(Entry $entry)
{
$category = Entry::find($entry->category_id)->categories()->first();
return view( 'entries.show', compact( 'entry', 'category' ) );
}
My categories table's up() method:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name', 255);
});
}
My entries table's up() method:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('entries', function (Blueprint $table) {
$table->id();
$table->string('title', 255);
$table->timestamps();
$table->integer('hours');
$table->integer('minutes');
$table->foreignId('category_id')->constrained('categories');
$table->string('difficulty', 255);
$table->string('url', 255);
});
Schema::enableForeignKeyConstraints();
}
You are fetching entry by category_id, no need to find the Entry again.
$category = Entry::find($entry->category_id)->categories()->first();
Should be
$category = $entry->category;
BelongsTo is a singular relation and can be described as below.
public function category() {
return $this->belongsTo(Category::class);
}

Call to a member function create() on null in laravel using Socialite

When I try to authenticate the user with using facebook so I am able to store data into the user table but the failure to create data into the soical_accounts.So after that errors with come up "call to a member funtion create() on null". Can anyone provide me solution that where I am wrong.
In my SocialAccountControll, I have the following method
public function handleProviderCallback($provider)
{
try{
$user = Socialite::driver($provider)->user();
} catch (Exception $e) {
return redirect('/login');
}
$authUser = $this->findOrCreateUser($user, $provider);
Auth::login($authUser, true);
// redirectTo, so that way we use the same redirect location that the rest of our authentication uses.
//This is a normal protected function that you can add in your users table to redirect a user wherever
// you want to set that redirect to.
//return redirect($this->redirectTo);
return redirect('/home');
}
public function findOrCreateUser($socialUser, $provider)
{
$account = SocialAccount::where('provider_name', $provider)->where('provider_id',$socialUser->getId())->first();
if($account)
{
return $account->user;
}
else
{
$user = User::where('email', $socialUser->getEmail())->first();
if(! $user)
{
$user = User::create([
'email' => $socialUser->getEmail(),
'name' => $socialUser ->getName()
]);
}
$user->accounts()->create([
'provider_name' => $provider,
'provider_id' => $socialUser->getId()
]);
return $user;
}
}
In my database migration, I have users and social_accounts and user have one to many relationship with social_accounts.
user table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->nullable();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->rememberToken();
$table->timestamps();
});
}
Social_accounts table:
public function up()
{
Schema::create('social_accounts', function (Blueprint $table) {
$table->increments('id');
$table->bigInteger('user_id');
$table->string('provider_name')->nullable();
$table->string('provider_id')->unique()->nullable();
$table->timestamps();
});
}
User Model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function accounts()
{
$this->hasMany('App\SocialAccount');
}
}
SocialAccount Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class SocialAccount extends Model
{
protected $fillable = [
'provider_name', 'provider_id'
];
public function user() {
return $this->belongsTo('App\User');
}
}
You are not returning anything here so change:
public function accounts()
{
$this->hasMany('App\SocialAccount');
}
To
public function accounts()
{
return $this->hasMany('App\SocialAccount');
}

I want only the authenticated users picture to show

Hello I am learning Laravel.
I have a picture gallery tha shows all pictures paginated but I want to only show on another page the users photos
So this is the controller for the only users photos to show
public function __construct()
{
$this->middleware('auth');
}
public function show(Photos $photos)
{
$user = auth()->user();
$images = Photos::all();
if($images->user->user_id==auth()->id())
{
return view('profile',['images'=>$images,
'user'=>$user]);
}
}
//This is my photos table
public function up()
{
Schema::create('photos', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('user_id')->index();
$table->string('title');
$table->string('image');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('photos');
}
public function up()
{
Schema::create('photos', function (Blueprint $table) {
$table->increments('id');
$table->unsignedinteger('user_id')->index();
$table->string('title');
$table->string('image');
$table->timestamps();
});
}
'
And this is the route:
//users gallery
Route::get('/profile','ProfileController#show')->name('profile');
This is my photos model:
// protected $guarded = [];
protected $fillable = [
'user_id','title','image'
];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
And this is my user model:
protected $fillable = [
'username','firstname','lastname','phone', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function photos()
{
return $this->hasMany(Photos::class);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function favorite()
{
return $this->hasOne(Favorites::class);
}
The problem is that is still shows all the photos not only the user's one. Please tell me what is that I am doing wrong?
your show method in your controller should be
public function show()
{
return view('profile',['images' => Photo::where('user_id', $user->id)->paginate(10),'user' => $user]);
}

Multiple laravel mappings, one side wont work

Hello guys I have made couple of classes with mappings as follows:
class Like extends Model
/**
* Returns like's author
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function owner(){
return $this->belongsTo('App\User');
}
/**
* Returns tweet
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function tweet(){
return $this->belongsTo('App\Tweet');
}
Class Tweet extends Model
/**
* Returns tweet's author
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function owner(){
return $this->belongsTo('App\User');
}
/**
* Returns tweet's likes
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function likes(){
return $this->hasMany('App\Like');
}
Class User extends Authenticatable
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'email', 'password', 'www', 'first_name', 'last_name', 'status'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
/**
* Returns user's tweets
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function tweets(){
return $this->hasMany('App\Tweet');
}
/**
* Returns user's likes
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function likes(){
return $this->hasMany('App\Like');
}
Now the problem is that two of my maping are not working. In Like model 'owner' method returns null, although its should return one record, 'tweet' method for the other hand works as expected.
In Tweet model the 'owner' method also returns null. All other methods are working as expected. I can't find where I have made mistake, and cannot rly understand why tweet method from Like model is working and owner is not....
Maybe Migrations find might be helpfull
public function up()
{
Schema::create('likes', function (Blueprint $table) {
$table->increments('id');
$table->integer('tweet_id');
$table->integer('user_id');
$table->string('status');
$table->timestamps();
});
}
public function up()
{
Schema::create('tweets', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('content');
$table->string('score');
$table->string('views');
$table->string('status');
$table->timestamps();
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('email')->unique();
$table->string('password',60);
$table->string('www');
$table->string('first_name');
$table->string('last_name');
$table->string('status');
$table->timestamps();
});
Both your Tweet & Like Models have owner() as their belongsTo() relationship method. Which is fine, but you'll have to specify the foreign key as second argument:
/**
* Returns like's author
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function owner()
{
return $this->belongsTo('App\User', 'user_id');
}
Laravel docs:
Eloquent determines the default foreign key name by examining the name of the relationship method and suffixing the method name with _id.
You have to specify the foreign key:
Schema::table('tweets', function ($table) {
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
});

Laravel - how to change table in orWhere method?

I want to do something like this:
$posts= Status::where('users_id',$user->id)->orWhere(DB::table('user_status_share.user_id', $user->id))->orderBy('created_at', 'DESC')->get();
But I'm getting an error: strtolower() expects parameter 1 to be string, object given - how can I change the table in "orWhere" method? Is this possible? If not - how to use 2 tables in one query?
Schema (Status):
public function up()
{
Schema::create('users_status', function (Blueprint $table) {
$table->increments('id')->unique();
$table->longText('status_text');
$table->integer('users_id')->unsigned();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users_status');
}
Schema (StatusShare):
public function up()
{
Schema::create('user_status_share', function (Blueprint $table) {
$table->increments('id');
$table->integer('status_id');
$table->integer('user_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('user_status_share');
}
Model Status:
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class Status extends Model
{
public $timestamps = true;
protected $table = 'users_status';
protected $guarded = ['id'];
public function comments()
{
return $this->hasMany(StatusComments::class);
}
public function likes()
{
return $this->hasMany(StatusLikes::class);
}
public function shares()
{
return $this->hasMany(StatusShare::class);
}
}
Model StatusShare:
<?php
namespace App\Eloquent;
use Illuminate\Database\Eloquent\Model;
class StatusShare extends Model
{
public $timestamps = true;
protected $table = 'user_status_share';
protected $guarded = ['id'];
public function status()
{
return $this->hasOne(Status::class);
}
}
I think you should try something like this
tweak it , i didnt test it
$posts = DB::table('status')->where('users_id',$user->id)->orWhere(function ($query) use ($user) {
$query->table('user_status_share')->where('user_id', $user->id);
})
->get();
can you share more informations because i have a feeling that these can be reached in a simple way using relations (show us database structure and relations in your models)

Categories