How to chain queries in laravel 5 - laravel

I used to do something like this in code Igniter
$this->db->select('*');
$this->db->from($this::DB_TABLE);
if ($role == "manager") {
$this->db->where('is_manager',1);
}
if ($role == "staff") {
$this->db->where('is_staff',1);
}
$this->db->where('is_active', 1);
$this->db->order_by('last_name', 'asc');
$user_set = $this->db->get();
return $user_set;
How can I write a similar query like this in laravel 5. I new to laravel.

If you want to conditionally change the query parameters it's like:
$query = Model::select('*')
if ($role == "manager") {
$query = $query->where('is_manager',1);
}
if ($role == "staff") {
$query = $query->where('is_staff',1);
}
$user_set = $query->where('is_active', 1)->orderBy('last_name', 'asc')->get();
return $user_set;
But I think it would be more succinct like this (totally untested, but I think this would work):
return Model::select('*')
->where('is_manager', $role == 'manager' ? 1 : 0)
->where('is_staff', $role == 'staff' ? 1 : 0)
->where('is_active', 1)
->orderBy('last_name', 'ASC')
->get();

Yeah but we have this pretty great Eloquent ORM that didn't exist in Codeigniter.
Now it looks like:
Model::where('is_manager', 1)->where('is_active', 1)->orderBy('last_name', 'DESC')->get()
It's similar, but WAY more powerful.
Study the Eloquent docs and check out some of the basic examples in the Laracasts tutorials.

Related

How can I store the conditions of a query Laravel

How can I store the conditions of a query into a variable so that I can call it later? I have a get method that returns a Builder, not a collection.
if($a == 1) {
$query = Review::query()
//many completely different conditions
->where('product_id', $data['product_id']);
}
if($a == 2) {
$query = Review::query()
//many completely different conditions
->where('product_id', $data['product_id']);
}
$reviews = $query->get();
You can use when()
$query = Review::query()
->when($a == 1, function($query){
$query->where('', '');
})
->when($a == 2, function($query){
$query->where('', '');
})
->where('product_id', $data['product_id'])
->get();

Laravel filter of multiple variables from multiple models

Goodmorning
I'm trying to make a filter with multiple variables for example I want to filter my products on category (for example 'fruit') and then I want to filter on tag (for example 'sale') so as a result I get all my fruits that are on sale. I managed to write seperate filters in laravel for both category and tag, but if I leave them both active in my productsController they go against eachother. I think I have to write one function with if/else-statement but I don't know where to start. Can somebody help me with this please?
These are my functions in my productsController:
public function productsPerTag($id){
$tags = Tag::all();
$products = Product::with(['category','tag','photo'])->where(['tag_id','category_id'] ,'=', $id)->get();
return view('admin.products.index',compact('products','tags'));
}
public function productsPerCategory($id){
$categories = Category::all(); //om het speciefieke id op te vangen heb ik alle categories nodig
$products = Product::with(['category','tag','photo'])->where('category_id', '=', $id)->get();
return view('admin.products.index',compact('products','categories'));
}
These are my routes in web.php. I guess this will also have to change:
Route::get('admin/products/tag/{id}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Route::get('admin/products/category/{id}','AdminProductsController#productsPerCategory')->name('admin.productsPerCategory');
For filter both
change your URL like
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Make your function into the controller like
public function productsPerTag($tagId = null, $categoryId = null){
$tags = Tag::all();
$categories = Category::all();
$query = Product::with(['category','tag','photo']);
if ($tagId) {
$query->where(['tag_id'] ,'=', $tagId);
}
if ($tagId) {
$query->where(['category_id'] ,'=', $categoryId);
}
$products = $query->get();
return view('admin.products.index',compact('products','tags', 'categories'));
}
You are trying to filter in your query but you pass only 1 parameter to your controller, which is not working.
1) You need to add your filters as query params in the URL, so your url will look like:
admin/products/tag/1?category_id=2
Query parameters are NOT to be put in the web.php. You use them like above when you use the URL and are optional.
2) Change your controller to accept filters:
public function productsPerTag(Request $request)
{
$categoryId = $request->input('category_id', '');
$tags = Tag::all();
$products = Product::with(['category', 'tag', 'photo'])
->where('tag_id', '=', $request->route()->parameter('id'))
->when((! empty($categoryId)), function (Builder $q) use ($categoryId) {
return $q->where('category_id', '=', $categoryId);
})
->get();
return view('admin.products.index', compact('products', 'tags'));
}
Keep in mind that while {id} is a $request->route()->parameter('id')
the query parameters are handled as $request->input('category_id') to retrieve them in controller.
Hope It will give you all you expected outcome if any modification needed let me know:
public function productList($tag_id = null , $category_id = null){
$tags = Tag::all();
$categories = Category::all();
if($tag_id && $category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->where('category_id' , $category_id)
->get();
} elseif($tag_id && !$category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->get();
} elseif($category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->where('category_id' , $category_id)
->get();
} elseif(!$category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->get();
}
return view('admin.products.index',compact(['products','tags','products']));
}
Route:
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');

Handling Scope with User Role Constraint - Laravel 5.3

If you try to look at the role name it doesn't really look good. I know this is not the best way to handle such condition. Is there a better way to do it?
public function scopeWishlist( $query ){
if( Auth::User()->role->name == "admin" || Auth::User()->role->name == "staff"){
return $query->where('transaction_type', '=', 1);
}
}
This is a much cleaner code
public function scopeWishlist($query, $role)
{
$roles = ['admin', 'staff'];
return (in_array($role, $roles)) ? $query->where('transaction_type', 1) : $query;
}
Then you can do something like
Model::where('blahblah', 'blahblah')->wishlist(auth()->user()->role->name)->get();
Hope it helps :)

Laravel 4 - Eloquent 'where' only if exists

I'm working in a search engine, and I have something like this in my Controller:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->where('position', $position)
->where('age', $age)
->orderBy('created_at', 'DES')
->paginate(10);
What I want is to use the $position and $age filters only if they exist. I mean, if I only set the keyword, I expect the application to show me all the users with this keyword (whatever its position and age are).
I know a way to do it... using if($position == '')... else..., but I would like to do (if possible) in my Eloquent consult. Something like... ->where('position' ? $position).
Any idea how to do it in the simplest way?
Thanks in advance!
Using if conditions would be the best way to do this. As far as I know the functionality your after isn't built into Eloquent.
I would do it using conditionals like so:
$query = User::where('description', 'LIKE', '%'.$keyword.'%');
if($position) {
$query->where('position', $position);
}
if($age) {
$query->where('age', $age);
}
$user = $query->orderBy('created_at', 'DES')->paginate(10);
If you want to keep your controller clean and avoid if - else you can create some scopes in your model.
For exemple :
public function scopePosition($query, $position)
{
//If $position in empty, return the query without where clause
return !($position == '') ? $query->where('position', $position) : $query;
}
And :
public function scopeAge($query, $age)
{
//If $age in empty, return the query without where clause
return !($age== '') ? $query->where('age', $age) : $query;
}
And then use it like this:
$user = User::where('description', 'LIKE', '%'.$keyword.'%')
->position($position)
->age($age)
->orderBy('created_at', 'DES')
->paginate(10);
More abour query scope:
http://laravel.com/docs/eloquent#query-scopes

Translate from CodeIgniter Active Record model to Laravel Eloquent

I am a CodeIgniter trying to adopt Laravel, however, I have been having a lot of problems understanding how to use Eloquent.
I suspect that if I could figure out how to translate some of my CodeIgniter Model methods to Laravel Eloquent I might be able to get on better. Hopefully, this will help others with the same problem.
Could anybody please rewrite the following from CodeIgniter to Eloquent:
public function get_products($product_id = NULL, $category_id = NULL, $limit = NULL)
{
$this->db->select('*, product.id AS product_id');
$this->db->from('product');
$this->db->join('product_unit', 'product.source_unit_id = product_unit.id', 'left');
$this->db->join('stock_levels', 'product.stock_level_id = stock_levels.id', 'left');
$this->db->join('categories', 'product.category_id = categories.cat_id', 'left');
if(isset($product_id)) {
$this->db->where('product.id', $product_id);
}
if(isset($category_id)) {
$this->db->where('product.category_id', $category_id);
}
if(isset($limit)) {
$this->db->limit($limit);
}
#$this->db->order_by('categories.cat_name', 'ASC');
$this->db->order_by('categories.cat_name', 'ASC');
$this->db->order_by('product.name', 'ASC');
$query = $this->db->get();
return $query->result_array();
}
Here's an approximate version of your query, there should be some things to tweak, but I hope you get the idea:
public function get_products($product_id = NULL, $category_id = NULL, $limit = NULL)
{
$query = Product::leftJoin('product_unit', 'source_unit_id', '=', 'product_unit.id')
->leftJoin('stock_levels', 'stock_level_id', '=', 'stock_levels.id')
->leftJoin('categories', 'category_id', '=', 'categories.cat_id');
if(isset($product_id)) {
$query->where('product.id', $product_id);
}
if(isset($category_id)) {
$query->where('product.category_id', $category_id);
}
if(isset($limit)) {
$query->limit($limit);
}
#$this->db->order_by('categories.cat_name', 'ASC');
$query->orderBy('categories.cat_name', 'ASC');
$query->orderBy('product.name', 'ASC');
dd( $query->toSql() ); /// this line will show you the sql generated and die // remove it to execute the query
return $query->get()->toArray();
}

Resources