I currently have a table called operators
The columns are:
id, user_id, item_clicked, created_at, updated_at
I can confirm on one of these it has today's update_at
2019-08-05 showing as today.
This is a relational table.
operators belongs to users.
I'm attempting to get operators of users whereDate is today.
My code is:
$ordersClicked = User::with('operators')
->whereDate('updated_at', \Carbon\Carbon::today())
->get();
This returns an empty array.
Testing this works so I know the data I need is there.
$ordersClicked = User::with('operators')
->get();
$operator = Operator::whereDate('updated_at', \Carbon\Carbon::today())->get();
Any idea what I'm doing wrong?
According to the docs https://carbon.nesbot.com/docs/ Carbon::today() returns Y-m-d H:i:s, if used like you are doing in a where clause and the database stores the value in Y-m-d format.
Why don't you try this:
$ordersClicked = User::with('operators')
->whereDate('updated_at', \Carbon\Carbon::today()->format('Y-m-d'))
->get();
if that doesn't work; then it is possible the eloquent is applying the where clause on updated_at on the User table, instead of Operator. Did you mean to do something like this:
$ordersClicked = User::with(['operators' => function($query) {
$query->where('updated_at', \Carbon\Carbon::today()->format('Y-m-d'))
}])->get();
i.e. filter on the eager loaded collection? if this is what you intended, what will happen is it will return all users and only some operators that has the updated_at matching the criteria will have values, where others will be null.
Wouldn't it be better to reverse the query? i.e. make sure Operator has a belongsTo relationship on User model and query the data like this:
$operator = Operator::whereDate('updated_at', \Carbon\Carbon::today())
->with('user')
->get();
Related
I have problem with my eloquent query, i need to use data of my base model into whereRelation.
I tried this query bottom, but results was not what i except. The query return me all users who have one city relation, not only user who have city updated between my last user sync.
$users = People::whereRaw('TIMESTAMPDIFF(SECOND, people.latest_sync, people.updated_at) > 20')
->orWhereRelation('city', 'updated_at', '>', 'people.updated_at')
->get();
I'v tried people.updated_at and latest_sync in value of my Where Relation
Do i need to make pure SQL Raw query with classic join ?
PS: the first whereRaw is ok, and work (i really need)
I have users and habits, and a habit_user table to join them.
I am querying like this:
$track = $h->userAnswers()->where('user_id', Auth::user()->id)->wherePivot('created_at', '=', Carbon\Carbon::now()->subDays($i))->first();
This is running in a loop that is counting back for 7 days. there is a record in the db that is created_at: 2018-10-23 04:48:44
In my habit model I have the method you'd expect:
public function userAnswers()
{
return $this->belongsToMany('App\Habit', 'habit_user_answers')->withTimestamps()->withPivot('answer_one', 'created_at')->orderBy('pivot_created_at', 'desc');
}
Why won't query get a record?
You are comparing the date time so only if both date and time is same, the query will throw a result.
You can compare dates like so:
wherePivot('created_at', '>=', Carbon\Carbon::now()->subDays($i)->startOfDay())->wherePivot('created_at', '<=', Carbon\Carbon::now()->subDays($i)->endOfDay())
First, I think you need to consider Laravel conventions about naming methods and properties.
I'll assume the following based on your structure that includes users and habits. So, we have a User model and a Habit model, a user belongsToMany habits and a habit belongsToMany users. Also the pivot table habit_user contains extra fields like answer_one, answer_created_at and timestamps.
If you want now to query the habits now you have two solutions:
1- using wherePivot()
auth()->user()->habits()->wherePivot('answer_created_at', today())->get();
auth()->user()->habits()->wherePivot('answer_one', '!=', 'something')->get();
2- using whereHas()
auth()->user()->whereHas('habits', function($query){
$query->where('pivot.answer_one', 'something');
})->get();
I have a query I am working on that feeds into a javascript engine where there is a lot of information returned that isn't used in the javascript. The results are over 1MB and some of that is because of some eager loading. Here is the query:
$customers = Customer::where('customers.office_id', $officeid)
->where("customers.parent_id", null)
->with('lastAppointment')
->with('nextAppointment')
->select("customers.id","customers.family_id", "customers.gender", "customers.family_size", "family_value")
->get();
The relationship of lastAppointment creates a returned nested object with all the columns from the appointments table, where I really only want a single column of start_at
If I do a ->leftJoin() I can limit my results using the final select like this:
->leftJoin(DB::raw("(select customer_id, MAX(start_at) as lastAppointment from appointments group by customer_id) as appt"), 'customers.id', '=', 'appt.customer_id')
->select("customers.id","customers.family_id", "customers.gender", "customers.family_size", "family_value", "appt.lastAppointment")
I am just wondering if there is a way of doing something similar using ->with()?
You can use this code
->with('lastAppointment:_relation_id,start_at')
where _relation_id is customer_id or primary key of lastAppointment correspond model: depends on your table relation. See docs part of Nested Eager Loading
https://laravel.com/docs/5.5/eloquent-relationships#eager-loading p
The with function will accept a callback as the array value of the relationship key. You then have access to the underlaying query builder instance, I think this is what you want:
->with(['lastAppointment' => function($query) {
return $query->latest()->select('customer_id', 'start_at')
->groupBy('customer_id');
}])
I have an eloquent query where I am not getting the expected results and I was hoping someone could explain to me what the correct way to write the query.
I have three tables:
records (belongsToMany users)
users (belongsToMany records)
record_user (pivot)
The record_user table also has a column for role.
I attempt to get all the records where the user has the role of either singer or songwriter:
$results = User::find(Auth::user()->id)
->records()
->wherePivot('role', 'singer')
->orWherePivot('role', 'songwriter')
->get();
Below is how the SQL syntax is generated:
select `records`.*, `record_user`.`user_id` as `pivot_user_id`,
`record_user`.`record_id` as `pivot_record_id` from `records`
inner join `record_user` on `records`.`id` = `record_user`.`property_id`
where
`record_user`.`user_id` = '1' and `record_user`.`role` = 'singer' or
`record_user`.`role` = 'songwriter'
The results for singer role are what is expected: All records where the user is the singer. The problem is the results for the songwriter: I am getting ALL songwriters and the query is not constrained by the user_id. For some reason I was expecting the songwriter role to also be constrained by the user_id - what is the correct way to write this using the eloquent syntax?
Hmm..I think you need to use an advanced where clause.
$results = Auth::user()
->records()
->where(function($query) {
$query->where('record_user.role', '=', 'singer')
->orWhere('record_user.role', '=', 'songwriter');
})
->get();
It is Laravel issue. In my case I solve it like this:
$results = Auth::user()
->records()
->wherePivot('role', 'singer')
->orWherePivot('role', 'songwriter')
->where('user_id', Auth::id())
->get();
Or use advance where clause
If your trying to get records I would do something similar to this:
User::find(Auth::user()->id)
->records()
->where(function($q){
$q->where('records.role', 'singer')
->orWhere('records.role', 'songwriter');
})->get();
If I do this:
return $this->roles()->detach($role);
all roles are removed.
How to limit that to only the last one?
You can do it without timestamps:
$lastRole = $user->roles()
->orderBy( $user->roles()->getTable() .'id', 'desc')
->first();
$user->roles()->detach($lastRole);
or with timestamps:
$lastRole = $user->roles()->latest()->first();
$user->roles()->detach($lastRole);
you may try this, I did not test it:
return $this->roles()->orderBy('id', 'desc')->first()->detach($role);
You can also order by timestamps, if no primary id is present, like this:
return $this->roles()->orderBy('created_at', 'desc')->first()->detach($role);
for this to work, you also have to edit your model, from the docs:
If you want your pivot table to have automatically maintained
created_at and updated_at timestamps, use the withTimestamps method on
the relationship definition:
return $this->belongsToMany('Role')->withTimestamps();
Another thing would be not to use model at all, because looking at this issue #3585 it is not that easy. Taylor closed it without a comment, so I assume it not get implemented. The solution should be (assuming you have timestamps columns migrated in the table). Tested code:
$last = DB::table($user->roles()->getTable())
->orderBy('created_at', 'desc')
->first();
DB::table($user->roles()->getTable())
->where('created_at', '=', $last->created_at)
->delete();