Laravel create simple drop-down from relationship and concat columns - php

i want to create simple drop-down inside html code from 2 table which they have single relationship, in my code i cant to get relationship data to concat that with other table columns. for example this is my code:
$user_accounts = UserAccountNumber::with('currencyType')->select('*', DB::raw('CONCAT("CardNumber: ", card_number) AS account_info'))
->whereUserId(Auth::user()->id)
->pluck('account_info', 'id');
this code work fine, but i want to conact some currencyType table columns with UserAccountNumber table and i cant use tableName.columnName into DB::raw()
for example:
$user_accounts = UserAccountNumber::with('currencyType')
->select(
'*',
DB::raw('CONCAT(" CardNumber: ", card_number, "CurrencyType: ", currencyType.title) AS account_info'))
->whereUserId(Auth::user()->id)
->pluck('account_info', 'id');
then i get this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'currencyType.currency_type' in 'field list' (SQL: select *, CONCAT("AccountNumber: ",account_number, " CardNumber: ", card_number, "CurrencyType: ", currencyType.currency_type) AS account_info from `user_account_numbers` where `user_id` = 17)
currencyType method in Model:
public function currencyType()
{
return $this->belongsTo(CurrencyType::class, 'currency_type', 'id');
}

Laravel does not use JOINs to do relationships, so you would have to write a specific query for that. Use query builder for that.
Something like this should work:
$user_accounts = DB::table('user_account_numbers')
->join('currencyType', 'user_account_numbers.currency_id', '=', 'currencyType.id')
->select('*', DB::raw('CONCAT(" CardNumber: ", card_number, "CurrencyType: ", currencyType.title) AS account_info'))
->whereUserId(Auth::user()->id)
->get();
I hope you get the idea and can adapt it to suit your database schema.

Related

How replace join query with whereHas?

I am using Laravel 5.6 and i have a standard query
Order::where('dict_statuses_id', 1)
->leftJoin('dict_statuses', 'dict_statuses_id', '=', 'dict_statuses.id')
->get();
So i have list of orders with details where status = 1 (new) after join table i see status as New or Complete. Is any way to change this query using whereHas ?
i tried use
Order::whereHas('status', function($q){
$q->where('dict_statuses_id', 1);
})->get();
But no results, in model Order i have
public function status()
{
return $this->hasMany('App\DictStatuses');
}
[Updated]
i have an error:
Column not found: 1054 Unknown column 'dict_statuses.orders_id'
in 'where clause' (SQL: select * from `orders` where exists
(select * from `dict_statuses` where `orders`.`id` = `dict_statuses`.`orders_id` and `dict_statuses_id` = 1)
and `orders`.`deleted_at` is null)
In my table i have table Orders where is field: dict_statuses_id
and table dict_statuses with fields: id, public_name
Why error is about dict_statuses.orders_id
Try Order::has('status')->get();
You can pass in variables to a relationship so you could potentially do.
public function status($id) {
return $this->hasMany(DictStatuses::class)->where('dict_statuses_id', $id);
}
Try defining the local key & foreign key.
$this->hasMany(DictStatuses::class, 'foreign_key', 'local_key');
I think your dict_statuses doesn't have a column called order_id.
Please include that column in your migration
then call
Order::whereHas('status', function($q){
$q->where('dict_statuses_id', 1);
})->get();
in your controller
or change the relation in Order model as
public function status(){
return $this->belongsTo('App\DictStatuses'):
}

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

Use concatenated columns in query with Eloquent

I am creating an api to search users. I am doing this in Eloquent, and I am wondering if there is any way to create a query with Eloquent like this:
SELECT * FROM users WHERE CONCAT('first_name', ' ', 'last_name') LIKE '%searchstring%' OR email LIKE '%searchstring%';
Is there a way to do this with the Eloquent query builder?
What I would like to do is essentially this:
$users = User::where('CONCAT(first_name, " ",last_name)', 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);
This results in Column not found: 1054 Unknown column 'CONCAT(first_name," ",last_name)' in 'where clause'
I was able to find the answer to this question, and the solution was to use the DB::raw method around the column name.
The working solution looks like this:
$users = User::where(DB::raw('CONCAT(first_name, " ",last_name)'), 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);
Try this:
$users = User::where(\DB::raw('CONCAT(first_name, " ",last_name)'), 'LIKE', '%searchstring%')->orWhere('email','LIKE','%searchstring%')->orderBy($ob, $dir)->paginate($perPage);

Concat columns using “with()” function in Laravel Eloquent

I'm trying to concat two columns from different tables into one single column.
$user = User::with(array('Person'=>function($query){
$query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id');
}))->lists('name', 'id');
In my person class I have this method:
public function User()
{
return $this->hasOne('User');
}
And in my user class I have this one:
public function Person()
{
return $this->belongsTo('Person', 'person_id');
}
I get the following error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'field list' (SQL: select `name`, `id` from `prefix_user`)
When I tried
$user = User::with(array('Person'=>function($query){
$query->selectRaw('CONCAT(prefix_person.name, " - ", prefix_user.code) as name, prefix_user.id')->lists('name', 'id');
}));
I got this error:
I have used the selectRaw a couple of times, but never needed it into a with (join).
The issue is that Eloquent will first query the users table, and only after, the persons table, so one query is not aware of the other and thus concatenating will not work.
You can use the Query Builder to do this using a join. It will be something like it:
$user = DB::table('users as u')
->join('persons as p', 'p.id', '=', 'u.person_id')
->selectRaw('CONCAT(p.name, " - ", u.code) as concatname, u.id')
->lists('concatname', 'u.id');
EDIT:
And, as suggested by #michel-ayres comment, as long as you have an acessor to the field:
public function getFullNameAttribute() {
return $this->attributes['name'] . ' - ' . $this->attributes['code'];
}
you can use your own model to perform the join and listing:
User::join('person','person.id','=','user.person_id')
->select('person.name', 'user.code', 'user.id')
->get()
->lists('full_name', 'id');
You can solve it simply by using simple query,
User::join('persons as p', 'p.id', '=', 'users.person_id')
->get([
'id',
DB::raw('CONCAT(p.name,"-",users.code) as name')
])
->lists('name', 'id');
Or, see another way
User::join('persons as p', 'p.id', '=', 'users.person_id')
->select(
'id',
DB::raw('CONCAT(p.name,"-",users.code) as name')
)
->lists('name', 'id');
You can solve it by using this sample query
->when($request->value != null, fn ($q) => $q->where(DB::raw("CONCAT(col1,'',col2)"), '=', '' . $request->value.
''))

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;
}

Categories