l5-repository
l5-repository copied to clipboard
(Need help ) having problem including relationship with repository
Hi! I would like to query shop_customers table that has the following shop ids and includes customers data on the query.
Shop Customer Model
class ShopCustomer extends Model implements Transformable
{
public function shop()
{
return $this->belongsTo(Shop::class, 'shop_id', 'id');
}
public function customer()
{
return $this->belongsTo(Customer::class, 'customer_id', 'id');
}
}
Shop Model
class Shop extends Model implements Transformable
{
public function user()
{
return $this->belongsTo(User::class);
}
public function shopCustomers()
{
return $this->hasMany(ShopCustomer::class);
}
}
Customer Model
class Customer extends Model implements Transformable
{
public function shopCustomers()
{
return $this->belongsTo(ShopCustomer::class, 'id', 'customer_id');
}
}
Now with eloquent I was able to solve this but I am using use Balping\HashSlug\HasHashSlug; on repository.
Eloquent
$shops = Shop::where('user_id', $user->id)->pluck('id')->toArray();
$customers = ShopCustomer::with('customer')->where('shop_id', $shops)->get()->toArray();
This is the equivalent query and it works except for displaying the slug
select `customer_id` from `shop_customers` where `shop_id` in (19)
select * from `shop_customers` where `shop_id` = 19
select * from `customers` where `customers`.`id` in (24, 25, 26)
and the output is this
info
array:3 [▼
0 => array:4 [▼
"id" => 15
"shop_id" => 19
"customer_id" => 24
"customer" => array:18 [▼
"id" => 24
"first_name" => "Colin 22"
"last_name" => "Powlowski"
"contacts" => "{"type":"mobile","number":"(866) 741-3896"}"
"email" => "[email protected]"
"notes" => "Vel iste possimus veniam. Ad unde cum sit. Veniam alias praesentium nesciunt rerum. Rerum repudiandae quaerat et nesciunt esse id voluptas fugit."
"company" => "Towne Ltd"
"referral_source" => "["website","friend"]"
"address1" => "8442 Florida Knolls Suite 679"
"address2" => "Suite 473"
"city" => "ton"
"province" => "Metro Manila"
"zip_code" => 4551
"tax_excempt" => 0
"discounted" => 0
"labor_override" => 0
"price_matrix_override" => 0
"deleted_at" => null
]
]
1 => array:4 [▶]
2 => array:4 [▶]
]
Any idea on how to implement this result using the repository? I tried the following
$customers = $this->newrep->with(['customer'])->whereHas('customer', function($query) use ($shops) {
$query->where('shop_id', $shops);
})->all();
The query that it does is
select * from `shop_customers` where exists (select * from `customers` where `shop_customers`.`customer_id` = `customers`.`id` and `shop_id` = 19)
select * from `customers` where `customers`.`id` in (24, 25, 26)
and returns
info
array:1 [▼
"data" => array:3 [▼
0 => array:5 [▶]
1 => array:5 [▼
"slug" => "mQ4ZA"
"shop_id" => 19
"customer_id" => 25
"created_at" => Carbon @1569392993 {#712 ▶}
"updated_at" => Carbon @1569392993 {#713 ▶}
]
2 => array:5 [▶]
]
]
Appreciate in advance any suggestions you can provide. Thank you!.
First of all I would like to say that according to your query variable $shops is an array of ids, then you must use whereIn method. Yours:
$shops = Shop::where('user_id', $user->id)->pluck('id')->toArray();
$customers = ShopCustomer::with('customer')->where('shop_id', $shops)->get()->toArray();
Suggestion:
$shops = Shop::where('user_id', $user->id)->pluck('id')->toArray();
$customers = ShopCustomer::with('customer')->whereIn('shop_id', $shops)->get()->toArray();
Secondly you can shorten code if $shops not needed further:
$customers = $user->shops()->with('shopCustomer.customer')->get()->pluck('shopCustomer')->toArray();
shops()
is a relation in User
model
public function shops(){
return $this->hasMany(Shop::class); // if user has one shop then replace hasMany with hasOne and change method name to `shop()` as it would more appropriate
}
and shopCustomer
is a relation in Shop
model
public function shopCustomer(){
return $this->hasMany(ShopCustomer::class);
}
or
$customers = ShopCustomer::with('customer')->where('shop_id', $user->shops()->pluck('id')->toArray())->get()->toArray();
or if $shops not an array of ids
$shop = Shop::where('user_id', $user->id)->first(); // $user->shop
$customers = ShopCustomer::with('customer')->where('shop_id', $shop->id)->get()->toArray();
Now coming to your issue, I am supposing these things:
- User has many shops because you have written this query:
$shops = Shop::where('user_id', $user->id)->pluck('id')->toArray();
-
$this->newrep
is instanceofShopCustomerRepository
implemented inShopCustomerEloquentRepositoy
. - You are using your own model in respective repository and not the Entities provided by the package.
To check this, your model ShopCustomer
namespace must be correct in ShopCustomerRepositoryEloquent
. It must be like App\ShopCustomers
or App\SomeOtherDirectory\ShopCustomer
if you models are located in a some other directory.
Your query:
$customers = $this->newrep->with('customer')->whereHas('customer', function($query) use ($shops) {
$query->where('shop_id', $shops);
})->all();
Solution 1 (staying as you are):
$shops = Shop::where('user_id', $user->id)->pluck('id')->toArray();
$customers = $this->newrep->with('customer')->findWhereIn('shop_id',$shops)->toArray();
or (if $shops not an array of ids)
$shop = Shop::where('user_id', $user->id)->first();
$customers = $this->newrep->with('customer')->findWhere('shop_id',$shop->id)->toArray();
Solution 1 End.
Solution 2 (if you are going add extra relations as I mentioned above):
add a new method userShopsRelatedShopCustomers()
, or name it as you like, in your ShopCustomerRepositoryEloquent
public function userShopsRelatedShopCustomers(){
$customers = $user->shops()->with('shopCustomer.customer');
return $customers;
}
and use it like:
$customers = $this->newrep->userShopsRelatedShopCustomers()->get()->pluck('shopCustomer')->toArray();
or
public function userShopsRelatedShopCustomers(){
$customers = $this->with('customer')->findWhere('user_id',$user->id);
return $customers;
}
and use it like:
$customers = $this->newrep->userShopsRelatedShopCustomers()->toArray();
Solution 2 End.
I again repeat if $shops (means array of ids) or $shop(means id), then replace the respective shop or shops function in User
model and correct naming according to it...