How to implement relationship in where condition Laravel's eloquent? - laravel

I have two tables:
Students
Results
The two tables have one to may relationship.
Student model:
public function results()
{
return $this->hasMany('App\Result');
}
Result model:
public function student()
{
return $this->belongsTo('App\Student');
}
In the students table I have a field called average_score.
How can I execute the following query, this is not working it says "Undefined property: Illuminate\Database\Query\Builder::$student":
$data = Result::with('student')->where('score', '>=', function($q){
$average_score = $q->student->average_score;
return $average_score;
})->get();
In order to get the results that are only higher or equal to than the "average_score".

If score and average_score are columns of the same table (student), try this;
$data = Result::with(['student' => function ($query) {
$query->whereColumn('score', '>=', 'average_score');
}])->get();
If score and average_score are columns of the different tables, try this;
$data = Result::with('student')->whereHas('student', function($q) {
$q->whereColumn('students.average_score', '<=', 'results.score');
})->get();

You can use whereHas to find those results:
$data = Result::with('student')->whereHas('student', function($q) {
$q->whereColumn('average_score', '<=', 'Results.score');
})->get();

get value from column Results.average_score then compare to student.score:
Result::with([
'student' => function($query) {
$query->where("score",">=", "Results.average_score"););
}
])

Related

How to get all the user data from another table and include them on user list in laravel?

I am using 2 tables upon displaying my users in my users>index.blade
these 2
USER table
and COLLECTOR_MEMBERS table
The result is this
Now my problem is I want to connect to the other table called
COMMISSIONS table
to achieve this result
MODELS
COMMISSIONS Model
USER
COLLECTOR MEMBER
USER Controller index function
public function index(Request $request)
{
$users = User::all();
$admins = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'admin');
})->get();
$collectorList = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector');
})->with('collectorList')->get();
$borrowers = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'borrower');
})->get();
$userProfile = Auth::user()->id;
if (Auth::User()->hasRole(['borrower','collector'])){
return redirect('dashboard/profile/'.$userProfile);
}
return view('dashboard.users.index', compact('users','profile'))
->with('admins',$admins)
->with('borrowers',$borrowers)
->with('collectorList',$collectorList);
// ->with('collectorBorrowers',$collectorBorrowers);
}
How wan I display the commission_amount column from commissions table? to make my list like this
You could use sum aggregate function, your code should look like this.
$collectorList = User::whereHas('roles', function ($q) {
$q->where('roles.name', '=', 'collector');
})->with(['collectorCommission' => function($query) {
$query->sum('commission_amount');
}])->get();
Assuming that you have this relationship in your user model
public function collectorCommission() [
return $this->hasMany('App\Commissions', 'user_id');
}
You cant use belongsToMany relationship since this relationship
requires you an intermediary table in your second argument.
You should use hasMany relationship considering that one user has many commissions.

eloquent - get sum of relationship column

My models are structured this way:
Stock (hasMany) StockItem
StockItem (belongsTo) Shipment
Shipment (hasMany) StockItem
- item_cost = double
So I'm trying to get all items and sum of their total_cost (located at Shipment model).
public function getStockItemsTotalCost($stockItemId=null){
$q = $this->stockItems()->where('id','=',$stockItemId)->with('shipment')->withCount([
'shipment AS cost_total' => function ($query) {
$query->select(DB::raw("SUM(item_cost) AS cost_total"));
}
]);
print_r($q);exit;
}
This is returning Allowed memory size of 268435456 bytes exhausted error.
Is this the best way to do this query?
I got a small progress
public function getStockItemSumCost($stockItemId){
$q = $this->stockItems()->whereHas('stockPart', function($q) use ($stockItemId) {
return $q->where('id', '=', $stockItemId);
})->with('shipment')
->get();
print_r($q->toArray());exit;
}
This is returning a StockItem list with Shipment inside each one...
What I need is a single column with the SUM() of all Shipment.item_cost column.
Solved with:
public function getStockItemSumCost($stockItemId){
$q = $this->stockItems()
->whereHas('stockPart', function($q) use ($stockItemId) { return $q->where('id', '=', $stockItemId); })
->join('shipments', 'stock_items.shipment_id', '=', 'shipments.id')
->sum('item_cost');
return $q;
}

Laravel eloquent model where datetime less than or equal

I am having an expire_datetime field in Test model and it has many relationship with Candidate model. I want to get all the tests which exipre_datetime is less than or equeal to now datetime. I am doing like this but I am getting all the records, date comparirion is not functioning.
Test Model:
public function testcandidates()
{
return $this->hasMany(Candidate::class,'test_id','id');
}
TestController:
$tests = Test::with([
'testcandidates' => function ($query) {
$query->where('result', '=', 'assigned');
}
])
->where('expire_datetime', '<=', Carbon::now('UTC'))
->get();
Try to get string from carbon: Carbon::now('UTC')->toDateTimeString()
$tests = Test::with(
['testcandidates' => function ($query) {
$query->where('result', '=', 'assigned');
}])
->where('expire_datetime', '<=', Carbon::now('UTC')->toDateTimeString())
->get();

Laravel, where, orwhere in main table an pivot table

I have two tables with belongsToMany relation: message_topics and users
The pivot table is message_topics_users and contains 2 columns: message_id and user_id.
In table message_topics, I have a field called sender_id
I'm trying to write the correct eloquent syntax to get all the records:
where message_topics.sender_id = $user_id
OR Message_topics_users.receiver_id = $user_id
I tried many things, like for instance:
$topics = MessageTopic::where('sender_id', $user_id)
->wherePivot('receiver_id', $user_id)->orderBy('sent_at','desc')->get();
Any idea?
You can use the whereHas method (or in this case the orWhereHas method):
$topics = MessageTopic::where('sender_id', $user_id)
->orWhereHas('users', function ($query) use ($user_id) {
$query->where('id', $user_id);
})
->orderBy('sent_at', 'desc')
->get();
I'm assuming you have two relationships from the topics? Since it's too arbitrary to use both columns and the same relationship... Like this
//On your MessageTopic model
public function sender(){
return $this->belongsToMany('App\User', 'message_topics_users', 'message_id', 'sender_id');
}
public function receiver(){
return $this->belongsToMany('App\User', 'message_topics_users', 'message_id', 'receiver_id'));
}
Then you can use whereHas and orWhereHas like this:
//Again assuming you have your User model loaded as $user
$topics = App\Topic::whereHas('sender', function($q) use($user){
$q->where('sender_id', '=', $user->id);
})
->orWhereHas('receiver', function($q) use($user){
$q->where('receiver_id', '=', $user->id
})
->orderByDesc('sent_at')
->get();
whereHas and orWhereHas both query the model (MessageTopic in this case) checking for the existence of the specified relationship (App\Topic::whereHas('sender')...). They also allow you to pass the constraint that you're looking for (function($q) use($user){ $q->... })
So it is basically saying "Give me ONLY the MessageTopics that have a Sender or Receiver with the id $user->id"

Excluding pivot rows in Eloquent ORM query

(laravel 4.2)
There are four tables involved; users, posts, flags, and post_flags.
I want to retrieve every post a certain user has, and retrieve the flags set for the post, but only the flags that are set by the user in question.
For example: A post can have flags: 1,2,2,3 where flag 2 is set twice. Once by User A, once by User B. I don't want to see the flags that User B has set.
The Eloquent query in my controller:
$posts = Post::whereHas('companies', function($q) use($company_id) {
$q->where('id', '=', $company_id);
})->with('flags')->get();
The Relation in my Post model:
public function flags() {
return $this->belongsToMany('PostFlag', 'post_postflags', 'post_id', 'flag_id')
->withTimestamps()->withPivot('owner');
}
How would I achieve this using Eloquent ORM?
UPDATE
My final query, thanks to andrewtweber:
Final query
$posts = Post::whereHas('users', function($q) use($id) {
$q->where('id', '=', $id);
})->get()->load([
'flags' => function($query) use($id) {
$query->where('owner', '=', $id)->orWhere('owner', '=', 'SYSTEM');
}
]);
Use wherePivot
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Relations/MorphToMany.html
$flags = $post->flags()
->wherePivot('user_id', '=', $user_id)
->get();
Or with eager loading
$posts->load([
'flags' => function ($query) use($user_id) {
$query->wherePivot('user_id', '=', $user_id);
}
]);

Resources