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]);
}
Related
I have a collection of genres for every movie and I wanna display every one that each movie has in the api request. Here's the resource:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'status' => $this->status,
'image_path' => url()->to('/images/' .$this->image_path),
'genres' => ''
];
}
I believe I need to access genres in Movie model and use foreach in toarray function but how exactly it should be done?
Here's my migrations:
public function up()
{
Schema::create('genres', function (Blueprint $table) {
$table->id();
$table->string('name');
});
}
public function up()
{
Schema::create('movies', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->integer('status')->nullable()->default(0);
$table->string('image_path')->default('default.png');
});
}
public function up()
{
Schema::create('genre_movie', function (Blueprint $table) {
$table->foreignId('genre_id')->constrained()->cascadeOnDelete();
$table->foreignId('movie_id')->constrained()->cascadeOnDelete();
});
}
Movie model:
class Movie extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['name', 'status', 'image_path'];
public function genres()
{
return $this->belongsToMany(Genre::class, 'genre_movie');
}
}
Genre model:
class Genre extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['name'];
public function movies()
{
return $this->belongsToMany(Movie::class, 'genre_movie');
}
}
Function in controller:
public function index()
{
return MovieResource::collection(Movie::paginate());
}
Create a genre resouce.
class GenreResource extends JsonResource
{
public function toArray($request)
{
return [
'name' => $this->name,
];
}
}
Load it in the controller using with().
public function index()
{
$movies = Movie::with('genres')->paginate();
return MovieResource::collection();
}
Add it to the MovieResource, use whenLoaded() and a closure, so you don't have to show it, if it is not loaded.
public function toArray($request)
{
return [
...
'genres' => $this->whenLoaded('genres', function () {
return GenreResource::collection($this->genres);
}),
];
}
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);
}
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');
}
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')
]);
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)