I have following tables
Messages:
user_id
group_id
text
created_at
And
group_users:
user_id
left_at
group_id
These tables have relationship via "group_id".
I need "Messages" that created before "group_user" left group.
In other word, i need a query like this:
$messages = Message::where('created_at','<',group_user.left_at)->get();
How can i achieve this?
You can simply do it like this assuming you have the user ID at hand:
Message::join('group_users', 'messages.group_id', '=', 'group_users.group_id')
->where('group_users.user_id', $id)
->where('group_users.left_at', '>', 'messages.created_at')
->get();
it can be like the code below(untested):
in the Message model
public function group(){
return $this->belongsTo(Group::class);
}
in the controller
$messages = Message::whereHas('group', function($q){
$q->where('left_at','>','messages.created_at');
})->get();
Related
I'm trying to group related model by pivot data, but this returns only one record of the related for each group. How can I group quiz records by column parent, which is saved in pivot table?
$user = User::where('id', $id)
->with(['quiz' => function($query) use ($md) {
$query->where('md_id',$md)->groupBy('pivot_parent');
}])
->first();
Try this and let me know what did you got
$user= User::where('id', $id)->whereHas('quiz', function($query)
use($md){
$query->where('md_id', '=', $md)-
>groupBy('pivot_parent');
})->first();
I am using two tables and a pivot table
Table 1 named calendars.
Table 2 named calendar_groups.
Pivot table calendar_calendar_group.
I'm trying to get data from Table 1 based on a where value in the pivot table. Where calendar_groups_id = 1 then use calendar_id to get data from table 1. I can't get it to work.
$event = new Calendar();
$event->orderBy('start', 'asc')
->whereHas('calendar_groups', function ($q) {
$q->wherePivot('calendar_groups_id', '=', '1');
})->with('calendar_groups')
->first();
This gives me the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pivot' in
'where clause'
This is the relationship:
public function calendar_groups()
{
return $this->belongsToMany(CalendarGroup::class);
}
Your help is very much appreciated.
I think #Tpojka is right here. If you're trying to get Calendar instances that belong to desired CalendarGroup then replace the code should look like this:
$event = new Calendar();
$group = 1;
$event->orderBy('start', 'asc')
->whereHas('calendar_groups', function ($q) use ($group) {
//$q->wherePivot('calendar_groups_id', '=', $group);
$q->where('id', '=', $group);
})->with('calendar_groups')
->first();
If I'm reading the documentation correctly wherePivot() should be used like this:
$event = new Calendar();
$event->calendar_groups()->wherePivot('some_pivot_column',1)->get();
But this would return you the CalendarGroup instances.
If you'd want to do it through Eloquent but without going all the way to the CalendarGroup then you'd probably need to create a Model (let's call it CalendarCalendarGroupPivot) for the pivot table and add another relation (hasMany('CalendarCalendarGroupPivot')) to your Calendar model.
Ok finally got it working.
I used your suggestions but still don't understand a little part of it.
When I use the suggestions made:
$event = new Calendar;
$event->orderBy('start', 'asc')
->whereHas('calendar_groups', function($q) {
$q->where('calendar_group_id', '=', '1');
})->with('calendar_groups')
->first();
I get an empty collection.
But if I run this:
$event = Calendar::orderBy('start', 'asc')
->whereHas('calendar_groups', function($q) {
$q->where('calendar_group_id', '=', '1');
})->with('calendar_groups')
->first();
I get the desired results
Can anybody tell me the difference between so I can learn from it?
Table: groups
id name status
Table: items
id group_id name publish
Model: Group
public function items()
{
return $this->hasMany('App\Item');
}
Now I want to get all group models where status is running and then all related item models where publish is published.
I do this...
$query = Group::where('status', 'running')->items()->where('publish', 'published')->get();
that shows the following Error Message.
Call to undefined method Illuminate\Database\Eloquent\Builder::items()
What's the wrong?
Is there any way to do this?
Note this EDIT:
**How will I get all item models where group model's status is running and item model's publish is published.**
You should try this:
$users = Group::whereHas('items', function($q){
$q->where('publish', 'published');
})
->where('status', 'running')
->get();
In your scenario, the query should look like this
$result = Group::whereHas('items', function($query){
$query->where("publish","published");
})
->where("status", "running")
->select('items')
->get();
$result will have all groups with status as running and all 'items' with publish status as published.
I'm having trouble with a one-to-many relationship in Laravel 5.5.
I have two tables, one for blog posts and one for authors. The posts table has an author_id column and it's populated with valid author IDs for each blog post. author_id is defined as a foreign key in the posts table migration.
When I load a view that uses the query the author is null because the author_id isn't being included in the generated query.
Post model:
public function author(): BelongsTo
{
return $this->belongsTo(Author::class);
}
I also tried explicitly listing the keys with the same result:
return $this->belongsTo(Author::class, 'author_id', 'id');
Post repository:
public function getPostBySlug(string $slug)
{
return $this->model
->select(
'posts.title',
'posts.contents',
'posts.published_at'
)
->with(['author:first_name,last_name,slug'])
->where('posts.slug', '=', $slug)
->whereNotNull('posts.published_at')
->first();
}
Generated query:
select `first_name`, `last_name`, `slug`
from `authors` where `authors`.`id` in ('')
and `authors`.`deleted_at` is null
You didn't select the posts.author_id so without the author_id the relationship couldn't be made, either select * or exclude the select statement or include posts.author_id in your select statement, for example:
$this->model
->select(
'posts.author_id',
'posts.title',
'posts.contents',
'posts.published_at'
)
// rest of the code ...
The foreign key (posts.author_id) has to be available to build the relationship with authors.
Try this
$users = DB::table('posts')
->leftJoin('authors', 'authors.id', '=', 'posts.user_id')
->select('posts.author_id','posts.title','posts.contents','posts.published_at',
'authors.first_name','authors.last_name','authors.slug')
->where('posts.slug', '=', $slug)
->whereNotNull('posts.published_at')
->first();
tray the ralation in the following way
:
return $this->belongsTo('namespace\author');
or reverse way
return $this->hasMany('namespace\author');
I have a query like:
$users = User::with('role')
->get();
How can I order the results by the related table, so it's something like:
$users = User::with('role')
->orderBy('role.id', 'DESC')
->get();
Is there a way to do it without joining the role table (since we're already doing with('role')?
what are you trying to order. the list of users or the roles.
if you are trying to sort the users base on role do.
$users = User::with('role')->orderBy('role_id', 'DESC')
->get();
if you are trying to sort the roles of the user then pocho's answer is correct.
$users = User::with(array('role' => function($query)
{
$query->orderBy('id', 'DESC');
}))->get();
From the documentation:
$users = User::with(array('role' => function($query)
{
$query->orderBy('id', 'DESC');
}))->get();
You can also do a raw query using DB::raw like in the examples here.
You can always sort the returned collection quite easily...
$users = User::with('role')
->get()
->sortBy(function($user, $key)
{
return $user->role->id;
});
This is assuming a user hasOne or belongsTo a role. If your relationship is something that can return multiple roles, then it becomes a bit more complex because you need to decide which of the user's roles to sort by.