Automatically add where clause to every queries on a model - php

Currently I am to do Model::where('status', 1) to filter off inactive models before adding any other subqueries to it. I find myself doing this all the time and Its quite stressful as sometimes I could forget to add that part. I wish to have something that will automatically add the where clause anytime I run a query on the model. Something that works like the typical Laravel SoftDeletes that adds the WHERE deleted_at IS NULL clause automatically to all queries.
Example:
Instead of writing Model::where('status', 1)->first(), I could just write Model::first() and this will be automatically transformed to Model::where('status', 1)->first().
How do I achieve this please ?

What you're looking are the
Query Scopes

Related

Question: how to use and with where in laravel

when I want to get data from a database in native PHP I use queries but in laravel, you don't write queries you use their model and their functions to get the data for example:
ex::where('name','test')->get();
in native PHP:
select * from ex where name='test'
and my issue is I don't know how to use and like this query:
select * from ex where name='test' and id='5'
I searched and looked thru the documentation but no answer was found.
Just put another where, its really simple just put it like this
ex::where('name', 'test')->where('id', 5)->get();
//or if you want directly the instance and not a collection
ex::where('name', 'test')->find(5);
If you want to use the OR operator you can also do something like this
ex::where('name', 'test')->orWhere('id', 5)->get();
More in documentations
There is no 'AND' with where in Laravel Eloquent.
You have to write another 'where' with the required condition.
Another way is: run queries using the DB facade. The DB facade provides methods for each type of query: select, update, insert, delete, and statement.
Ex. DB::statement("UPDATE teachers SET price = ".$price." where id=".$id." AND status='A'");
Do not forget to use DB

Use a join statement and save the results as a relation like "with" does? - Laravel 5.2

I'm trying to get data from multiple relationships. But I don't want to end up with multiple queries. So the with method won't work for me.
I want to use joins to get the data needed, but laravel overwrites keys if they are duplicated. Is there a way to save the results from a join as a relation. Something like this below (join is incorrect I know).
Post::select('post.*', 'category.*')->join('category');
If both have an 'id' field it's overwritten by the other. So I would like to have category.* results as a relation so I can call ->category->id like I can when I use the with method.
Is there any way to do this?
You may use the whereHas and orWhereHas methods
Check this link:
http://laravel.io/forum/04-19-2014-many-to-many-to-many-in-wherehas
And Laravel Documentation:
https://laravel.com/docs/5.1/eloquent-relationships

Laravel - Execute function before query is fired

is there a way for Eloquent/raw queries to execute a function before a query is fired? It would also be nice if I could extend the functionality to pass a parameter if the function should be run before or not. Depending on the outcome of the function (true/false) the query shouldn't be executed.
I would be nice to use the principal of "DB::listen", but I'm not sure if I can stop or run the query from within this function.
The reason for this is that I would like to build a little data warehouse myself for permanently saving results to a warehouse (db) and not query a huge database all the time.
The method I'm would like to use is to create a hash of a query, check if the hash exists in the warehouse. If it exists, then the value is returned. If not the query is executed and the output is saved together with the hash into the warehouse.
Any ideas?
///// EDIT /////
I should clarify, that I would like to access the queries and update the value if the calculated value needs to be updated. i.e.: Number of cars in december: While I'm in december, I need to keep updating the value every so often. So I store the executed query in the db and just retrieve it, run it and then update the value.
//// EDIT 2 /////
Github: https://github.com/khwerhahn/datawarehouselibrary/blob/master/DataWareHouseLib.php
What I would like to achieve is to hook into Laravels query/Eloquent logic and use the data warehouse logic in the background.
Maybe something like this:
$invalid_until = '2014-12-31 23:59:59'; // date until query needs to be updated every ten minutes
$cars = Cars::where('sales_month', '=', 12)->dw($invalid_until)->get();
If the dw($date_parameter) is added I would like Laravel to execute the data warehouse logic in the background and if found in the db then not execute the query again.
You don't need to use events to accomplish this. From the 4.2 docs:
Caching Queries
You may easily cache the results of a query using the remember method:
$users = DB::table('users')->remember(10)->get();
In this example, the results of the query will be cached for ten
minutes. While the results are cached, the query will not be run
against the database, and the results will be loaded from the default
cache driver specified for your application.
http://laravel.com/docs/4.2/queries#caching-queries
You can also use this for Eloquent objects,
eg: User::where($condition)->remember(60)->get()
I get what you're trying to do, but as I view it (I might not still be getting it right, though) you still can get away with using rememberForever() (if you don't want a specific time limit)
So, let's pretend you have a Cars table.
$cars = Cars::where('sales_month', '=', 12)->rememberForever()->get();
To work around the problem of deleting the cache, you can assign a key to the caching method, and then retrievit by that key. Now, the above query becomes:
$cars = Cars::where('sales_month', '=', 12)->rememberForever('cars')->get();
Every time you run that query you will be getting the same results, first time from the DB, all the others from the cache.
Now you say you're going to update the table, and you want to reset the cache, right?
So, run your update, then forget() the Cache with the cars index:
// Update query
Cache::forget('cars');
Your next call to the Cars query will issue a new resultset, and it will be cached. In case you're wondering, the remember() and rememberForever() are methods of the QueryBuilder class that use the same Cache class you can see in the docs in its own section.
Alternatively, in fact, you could also use the Cache class directly (it gives you a better control):
if (null == $cars= Cache::get('cars')) {
$cars = Cars::where('sales_month', '=', 12)->get();
Cache::forever('cars', $cars);
}
By overriding the method runSelect exsists in Illuminate\Database\Query\Builder that runs in every select query in Laravel.
see this package:
https://github.com/TheGeekyM/caching-queries

yii relation HAS_MANY add condition

I write this line at my controller
<i>
$model_town=ResTown::model()->with(array('get_by_town'))->findAll(array('limit'=>'3'));
</i>
I need to make get_by_town with limit=3 and user_active=1
I got all records but conditions don't work
If you would like to add condition on related table you should write it inside with() method.
So, you should get something similar `
->with('get_by_town'=>array('limit'=>3, 'user_active'=>1))
But in some cases it can not helps you, because it depends on many things: for example, relation type, join type and so on.
The easiest way to work with ActiveRecord for me, first of all write down pure sql, and then convert to ActiveRecord representation. Thus, I get optimized query and exactly knowing of what I'm doing %)

Laravel 4 Build Query where clause on the fly

I am porting my code from CodeIgniter to Laravel. and have some question regarding the query builder.
In codeigniter, I can just add where clause to the active record object, as I initialize each property in a class like
$this->db->where('xxxx','bbbb');
in one property initialize function, and
$this->db->where('yyyy','aaaa');
in another property function, and it will all chain up until i fire off the query. But this doesn't seem to be the case of Laravel.
Here is what I do in laravel in each property initialize function
DB::table($this->table)->where('xxxx','bbbb');
DB::table($this->table)->where('yyyy','aaa');
and when a actual method is call from outside, it runs
DB:table($this->table)->get();
but this gives me a SELECT * FROM TABLENAME without anywhere clause. So what am I doing wrong here :x or I just shouldn't treat laravel same as codeigniter and think of something totally different to handle this kind of dynamic where clause?
Also in codeigniter, you can set a section of the query to cache, so even after you fire off the query , those section retains for next query, usually the where clause. Is there a similar function in Laravel? Thank you!
You can assign your current workings to a variable, and build upon that, let me show you an example based on your example:
Instead of this
DB::table($this->table)->where('xxxx','bbbb');
DB::table($this->table)->where('yyyy','aaa');
Try this...
$query = DB::table($this->table)->where('xxxx','bbbb');
$query->where('yyyy','aaa');
$results = $query->get();
I just shouldn't treat laravel same as codeigniter and think of something totally different to handle this kind of dynamic where clause?
This is not dynamic where clause.
and please, make a habit of reading the documentation.
From the docs of Fluent query builder
$users = DB::table('users')->where('votes', '>', 100)->get();
you can set a section of the query to cache, so even after you fire off the query , those section retains for next query, usually the where clause. Is there a similar function in Laravel?
$users = DB::table('users')->remember(10)->get();
Next time, just open up the docs. they contain all this.

Categories