i have two tables :: shops
and attachments
. Shops has all the details for shop and attachments with all the pictures for shop with ref_id
as FK .
now for mobile app i have to list shops with Shop title and one image. I can achieve it using leftjoin as below.
Shop::select('shops.name as shop_name','attachments.name as picture')
->leftjoin('attachments','attachments.ref_id','=','shops.shop_id')
->paginate(10);
This returns just shop name and pictures , I want to achieve same results using relationships that i am not sure of how can i do that. Can someone please advise me on that
Edit
Shop Model
public function attachments(){
return $this->hasMany(Attachment::class, 'ref_id', 'shop_id');
}
dd(Shop::find(34)->attachments()->first());
dd(Shop::with('attachments')->get());
using first dd returns me attachment associated with 34 and but with query is not working and returns just shop
CodePudding user response:
First of all, add the attachments relationship function to the Shop
model.
class Shop
{
...
public function attachments()
{
return $this->hasMany(Attachment::class, 'ref_id', 'shop_id');
}
}
Then you can access shop attachments by using the ->attachments()
on the Shop
objects.
Example for getting all with pagination: (eager loading)
$shops = Shop::with('attachments')->paginate(10);
# access to first attachment of first shop
$shops->first()->attachments->first()->name
Note: It's better to use eager loading when you want to access all shops attachments to prevent the N 1 query problem
CodePudding user response:
I guess you have to define a One to Many relation in your Shop model (because one shop can have multiple attachements).
Maybe something like this :
// In Shop model
public function attachments()
{
return $this->hasMany(Attachment::class, 'ref_id', 'shop_id');
}
Then you can use it like this (you don't have to use the find, you can use a where if you want) :
$attachment = Shop::find(1)->attachments()->first();
https://laravel.com/docs/9.x/eloquent-relationships#one-to-many