I want to count contributions rows with is references to pools ( a Pool has many Conributions)
$pool->with(array('contributions' => function($q) use($pool){
$q->where('status', '=', 'completed');
}))->count();
But i can't get the correct result.
Your Contribution model could have:
class Contribution extends Eloquent {
public function pool() {
return $this->belongsTo('Pool');
}
}
Your Pool model should have:
class Pool extends Eloquent {
public function contributions() {
return $this->hasMany('Contribution');
}
Query
$pool->contributions()->where('status', '=', 'completed')->count();
What about this?
$pool->whereHas('contributions', function($q){
$q->where('status', '=', 'completed');
}))->count();
Related
I'm trying to load a relationship with eager loading. But, would like to pass an attribute to the relationship function.
(Laravel 6.x)
Model - taxChildren() requires an ID
public function taxChildren($moduleId)
{
return $this->hasMany($this, 'parent')->where('module', '=', $moduleId')->orderBy('created_at', 'asc');
}
Controller
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => ['moduleId', '2']
])
->get();
Now , i know that i can pass a query to my relationship like so:
$departments = tax::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with([
'taxChildren' => function($query){
$query->where('module', '=', $this->departmentsModuleId);
},
])
->get();
but i will be using this often with multiple relations that are similar. Anyone have an idea how to achieve this? Thanks!
You can't pass argument direcly to the relationship function but this can be done with model properties
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$query = new MyModel;
$query->moduleId = 1;
$departments = $query::where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}
Also you can use laravel query scopes to set modelId property . I think that is much cleaner code
Mymodel.php
class MyModel extends Model {
protected $moduleId = null;
public function scopeMudule($q, $module_id){
$this->moduleId = $module_id;
return $q;
}
public function taxChildren(){
return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
}
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {
public function controllerMethod(){
$departments = $query::module(1)->where([
['module', '=', $this->departmentsModuleId],
])
->whereNull('parent')
->with(['taxChildren'])
->get();
}
}
I have two models Client and Group.
This is many to many relationships where the client belongs to many groups and groups have more than one client.
I want to get all the clients that not already belong to a group and pass it to the view.
Group Model:
public function clients() {
return $this->belongsToMany('App\Models\Client', 'client_group', 'group_id', 'client_id');
}
Client model:
public function documents() {
return $this->belongsToMany('App\Models\Document', 'client_document', 'client_id', 'document_id');
}
GroupsController.php
public function edit($id)
{
$group = Group::find($id);
$clients = Client::all()->where('user_id', Auth::user()->id);
return view('backend.groups.edit', compact('group', 'id', 'clients'));
}
If I understand correctly, you want clients that are not part of a group. Essentially, you need to query relationship absence:
$clients = App\Client::doesntHave('groups')->get();
If you want to have the ability to add additional where clauses:
use Illuminate\Database\Eloquent\Builder;
...
$clients = App\Client::whereDoesntHave('groups', function (Builder $query) {
$query->where('active', '=', true);
})->get();
For more information see Querying Relations
I have a collection of products for a particular order like this ->
$products = $order->products()->with('store.seller')->get();
What I want to get is a $sellersCollection where,
each $seller has $stores
each $store has $products
[$seller - stores - products]
How can it be done efficiently without making another db call.
using eloquent relationship you can access this.use appropriate relationship hasOne() or hasMany() in your model.Ex. Seller->hasOne(store) and store->belongsTo(seller) like that.
Doing with eloquent way you could get the desired results as
$sellers = Seller::with('stores.products')->get();
Above will return you all sellers with their related stores and each store with their related products
class Seller extends Model{
public function stores(){
return $this->hasMany('App\Store', 'seller_id')
}
}
class Store extends Model{
public function products(){
return $this->hasMany('App\Product', 'product_id')
}
}
I believe order and products are related as m:m via pivot table so you could define their relation as belongsToMany
class Product extends Model{
public function orders(){
return $this->belongsToMany('App\Order')
}
}
Edit I want the particular $sellers who are associated with the order just made and with all the info of the products buyer ordered like quantity
$sellers = Seller::with(['stores.products.orders' => function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
}])
->whereHas('stores.products.orders', function ($query) use ($orderId) {
$query->where('id', '=', $orderId);
})
->get();
I have two models Room and Booking.
The models are as follows:
class Room extends Model {
public function bookings() {
return $this->hasMany(Booking::class);
}
}
class Booking extends Model {
public function room() {
return $this->belongsTo(Room::class);
}
}
I want to use laravel's eloquent to select all Rooms that do not have a booking at a given date, say, 2018-06-07.
I have tried the following:
$available_rooms = Room::whereHas('bookings', function($query) {
$query->where('date', '!=', '2018-06-07');
})->get();
However, this only returns the rooms that have any bookings and not those that do not have any at all.
Thank you for your help.
You can use doesntHave()
$available_rooms = Room::doesnthave('bookings','or' ,function($query) {
$query->where('date', '!=', '2018-06-07');
})->get();
It will return the rooms that are not booked for this day.
for more information, you can https://laravel.com/api/5.4/Illuminate/Database/Eloquent/Builder.html#method_doesntHave
Hope this helps.
You can use doesntHave
$available_rooms = Room::doesntHave('bookings', function($query) {
$query->where('date', '!=', '2018-06-07');
})->get();
I'm creating an application with Laravel and I'm trying to work with Eloquent. I have two tables : Orders and Items.
Each items has a type (int data) :
1 => book
2 => video
Each order has ONE book and many videos.
In my Order model, I would like to have a book and others items relationships. So, I have this code :
public function book()
{
return $this->hasMany('App\Item')->where('type', 1)->first();
}
public function others()
{
return $this->hasMany('App\Item')->where('type', '!=', 1)->get();
}
But, if I use eager loading with my relationship, I got an error :
Order::with(['book', 'others'])->get();
Can you help me to solve this problem ?
Thanks
Define relationships like this to make your code work:
public function book()
{
return $this->hasOne('App\Item')->where('type', 1);
}
public function others()
{
return $this->hasMany('App\Item')->where('type', '!=', 1);
}
But it's better to define relationships without where constraints:
public function book()
{
return $this->hasOne('App\Item');
}
public function others()
{
return $this->hasMany('App\Item');
}
And then do this:
Order::with(['book' => function ($q) {
$q->where('type', 1);
},
'others' => function ($q) {
$q->where('type', '!=', 1);
}])
->get();