Get all records value is not 1 in Laravel - laravel

How can I get all records from the table where status value is 0 or NULL on Laravel?
DB::table('categories')->where('status', '!=', 1)
returns only records where status=0
P.S. I need multiple conditions here, so raw query is not so good choice.

You said you'll have another where conditionals, so you need to use a closure:
DB::table('categories')->where(function($q) {
$q->whereNull('status')->orWhere('status', 0);
})
// Other where conditionals.
->get();

You can use orWhereNull:
DB::table('categories')->where('status', '=', '0')->orWhereNull('status')->get();

Related

Laravel eloquent query with nested whereDate

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();

Laravel 5 Query builder

I tried advanced where clauses
i have model with 2 datetime columns start and end
the request comes two values date_start, date_end
my code
->where(function($q) use ($date_start,$date_end) {
$q->where('start','>=',$date_start)
->where('end','<=',$date_start)
->where('start','>=',$date_end)
->where('end','<=',$date_end);
})
->first();
code returned nothing but in table have one record,
values on request suitable. What is wrong?
worked
$q->where('start','<=',$date_start)
->where('start','<',$date_end)
->where('end','<=',$date_end);

Laravel Eloquent orWherePivot Not Returning Expected Result

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();

How to detach only the last record in the pivot table using detach() in Laravel 4?

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();

Eloquent ORM, how to avoid redundant queries?

Suppose I have the field status in all my database tables. When I want to delete a record, instead of purging it I set the value of field status to 0. This means of course all my queries will always use a where clause such as:
WHERE status = 1
However, this means I have to write and append where('status', '=', 1) to all methods of my eloquent model. It will always be like:
Post::find(1).where('status', '=', 1)
Post::where('status', '=', 1)->get()
Post::find(1).where('status', '=', 1).comments().where('status', '=', 1)->get()
Is there a way to define something as a default scope to have where status = 1 always present in all methods of my model and all the time?
I appreciate any help!
This should do the trick, at least regarding soft delete:
http://four.laravel.com/docs/eloquent#soft-deleting
You could use the scope methods.
public function scopeActive($query)
{
$query->where('status', '=', 1);
}
Then, you use like this:
Post::active()->get();

Resources