Laravel on sorting related model? - php

I know from laravel documentation that I can do eager loading like:
$records = (new Route)->with('country')->get();
But when I execute this:
$records = (new Route)->query()->with('country')->orderBy('country.name', 'asc')->paginate();
I get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'country.name' in 'order clause' (SQL: select * from `routes` order by `country`.`name` asc limit 2 offset 0)
How I can sort on related model ?
How can I force laravel to load joined tables?

I find the solution:
$records = (new Route)->query()->join('countries', 'routes.country_id', '=', 'countries.id');
But is not ideal because joining are performed manualy.

You can do the following with eager loading :
$records = (new Route)->with(['country' => function ($q) {
$q->orderBy('name', 'asc');
}])->get(); // or paginate or whatever

Related

How to Join two different tables in Laravel

QueryException in Connection.php line 729:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'site_name' in
'where clause' (SQL: select email_date, url, recipient from
report_list where site_name = mywebsite)
$records = DB::table('report_list')
->select('email_date','url','recipient')
->where('site_name',$site_name)
->get();
return records;
return view('monthlyReport')
->with('records',$records)
->with('site_name',$site_name);
My site_name was on different table and I don't know if I need to put Join or Make a model for this two.
Can someone help me with this query?
First of all You need to add column named "site_name" to your "report_list" table in database.
this query is for you to join 2 tables (here I took example "users" table as second table If your second table is defferent use your) ->
$records = DB::table('report_list')
->join('users', 'report_list.user_id', '=', 'users.id')
->where('report_list.site_name', '=', $site_name);
->select('users.*', 'report_list.email_date','report_list.url','report_list.recipient')
->get();
return view('monthlyReport')
->with(['records' => $records , 'site_name' => $site_name ]);
If you show the tables to see the columns and table names could help you better, while these are some examples:
//Option 1
$results = DB::table('users')
->join('business', 'users.id', '=', 'business.user_id')
->select('users.*', 'business.name', 'business.telephone', 'business.address')
->get();
//Option 2
$results = User::join("business as b","users.id","=","business.user_id")
->select(DB::raw("users.*"), "b.name as business_name", "b.telephone as business_telephone", "b.address as business_address")
->get();
The laravel docs: https://laravel.com/docs/5.6/queries#joins
You should create a model for your other table which I assume it's Site then in the report_list model create a relation method like :
public function sites(){
return $this->hasOne(Site::class);
}
or:
public function sites(){
return $this->hasOne('App\Models\Site);
}
After that in your eloquent query use this :
$records = DB::table('report_list')
->select('email_date','url','recipient')
->whereHas('sites', function($query){
$query->where('site_name',$site_name);
})
->with('sites')
->get();

Laravel - Eloquent - Return Where Related Count Is Greater Than

I have 2 tables.
Products
Brands
Im trying to return top 10 brand models with the most products.
I've tried.
Product::select('brand', DB::raw('count(brand) as count'))->groupBy('brand')->orderBy('count','desc')->take(10)->get();
But that doesn't return the hole model and only returns
Brand
Count
I've also tried
return $brands = Brand::whereHas('products', function($q) {
$q->count() > 10;
})->get();
But I get the error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'brands.id' in
'where clause' (SQL: select count(*) as aggregate from products
where brands.id = products.brand)
My Brand Model
public function products()
{
return $this->hasMany('App\Product','brand');
}
My Product Model
public function manuf()
{
return $this->belongsTo('App\Brand','brand');
}
try this:
$brands = Brands::has('products', '>' , 10)->with('products')->get();
You should be able to accomplish this with the withCount method if you're using at least Laravel 5.3:
Brand::withCount('products')->orderBy('products_count', 'DESC')->take(10)->get();
Where products is the name of your relation. This will give you a new field in your query, products_count that you can order by.

Laravel Eloquent - Query builder cant find column with having function

I have a pivot table 'game_genre'(with game_id and genre_id). The game and genre model has a belongsToMany relationship similar to example below.
I have been attempting to gather the games which contain both genre_id of 60 and 55 together. I have been getting the correct result using the following SQL query, but when using the following query builder I end up getting a column not found error when using the having() function.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'genre_id' in 'having clause'
Im not sure how else to structure the query builder?
MODEL:
class Game extends Model
{
public function genres()
{
return $this->belongsToMany('App\Genre');
}
}
SQL:
SELECT *
FROM game_genre
WHERE genre_id = 55 OR genre_id = 60
GROUP BY game_id
HAVING COUNT(DISTINCT genre_id) = 2;
CONTROLLER:
$game = Game::whereHas('genres', function ($query)
{
$query->where('genre_id', '55')
->orWhere('genre_id', '60')
->groupBy('game_id')
->having('genre_id','=', 2);
})->get();
You forgot the aggregate function (in this case COUNT) in your HAVING condition:
$query->where('genre_id', '55')
->orWhere('genre_id', '60')
->groupBy('game_id')
->havingRaw('COUNT(DISTINCT genre_id) = 2');
Instead of adding several where() and orWhere() to your query, you could also use whereIn() which takes an array:
$myArray = [55,60];
$query->whereIn('genre_id', $myArray)
->groupBy('game_id')
->havingRaw('COUNT(DISTINCT genre_id) = 2');
You can use the following query to get the Games which contain both genre_id of 60 and 55:
$games = Game::whereHas('genres', function ($query) {
$query->where('genre_id', '55');
})
->whereHas('genres', function ($query) {
$query->where('genre_id', '60');
})
->get();

Filter on laravel pivot table

I have two tables in Laravel connected with a pivot table. The two tables are users and roles, and the pivot table is called role_user. The pivot table also contains two extra fields: start and stop. This way I can track which roles a user has had in the past.
Now I want to create a query that gets all users who currently have role_id = 3.
First I had used WherePivot, but apparently that is bugged.
I have now made the following query using Eloquent:
Role::with('User')
->where('id', '=', '3')
->where('role_user.start', '<', date('Y-m-d'))
->where('role_user.stop', '>', date('Y-m-d'))
->whereHas('users', function($q){
$q->where('firstname', 'NOT LIKE', '%test%');
})
->get();
But somehow I am getting an error that the column start of the pivot table cannot be found. But I can confirm in PHPMyAdmin that the column is there.
This is the entire error:
Illuminate \ Database \ QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'klj_role_user.start' in 'where clause' (SQL: select * from `klj_roles` where `id` = 3 and `klj_role_user`.`start` < 2014-06-02 and `klj_role_user`.`stop` > 2014-06-02 and (select count(*) from `klj_users` inner join `klj_role_user` on `klj_users`.`id` = `klj_role_user`.`user_id` where `klj_role_user`.`role_id` = `klj_roles`.`id` and `firstname` NOT LIKE %test%) >= 1)
Can someone tell me if I am doing something wrong or give me a hint where I should be looking now?
The error is telling you that you are missing the start column in your pivot table klj_role_user. What you should do is create the column. If the column is already there, ensure you are using the correct database.
I've also simplified your query a little bit. You don't really need a whereHas because you aren't trying to limit your roles by the users associated, but by the id, which in this case, you are using 3. A with() would work perfectly fine and wherePivot() seems to be working fine for me when used in conjunction with with().
$role = Role::with(array('users' => function($q)
{
$q->wherePivot('start', '>', date('Y-m-d H:i:s'));
$q->wherePivot('stop', '<', date('Y-m-d H:i:s'));
$q->where('firstname', 'NOT LIKE', '%test%');
}))->find(3);
foreach($role->users as $user) {
echo $user->firstname;
}

Laravel 3 - Order by the division of two fields

I need following SQL converted to eloquent
select * from medias order by likes/views DESC, views ASC
I need to use paginate on the result, that is why i prefer eloquent.
Some of my other SQL queries are
$media_list = Media::order_by('likes', 'desc')->paginate($per_page);
I tried
$media_list = Media::order_by('likes/views', 'desc')->paginate($per_page);
But it gives error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'likes/views' in 'order clause'
SQL: SELECT * FROM `medias` ORDER BY `likes/views` DESC LIMIT 20 OFFSET 0
Anyone know how to fix this ?
Try , instead of /
$media_list = Media::order_by('likes,views', 'desc')->paginate($per_page);
or
$media_list = Media::order_by('likes`,`views', 'desc')->paginate($per_page);
And also this is the standard way of doing in laravel
$media_list = Media::order_by('likes', 'desc')->orderBy('views', 'desc')->paginate($per_page);
$media_list = DB::table('medias')
->select(DB::raw('(likes/views) AS resultant'))
->order_by('resultant', 'desc')->orderBy('views', 'desc')
->get();

Categories