I have models User and Profile with hasOne relationship as following:
class User extends Model
{
public function profile()
{
return $this->hasOne(Profile::class, 'user_id');
}
}
I want to select all users by full_name attribute of Profile in Laravel way. I have tried to this code but it return all the users in user table.
User::with(['profile' => function ($q) use ($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
}]);
Any idea? Thanks so much.
Try whereHas method like:
User::whereHas('profile', function($q) use($request) {
$q->where('last_name', 'LIKE', '%' . $request->input('name') . '%');
});
Related
There is a Model named Profile that has user relation.
public function user(){
return $this->belongsTo(User::class);
}
and the profile table column is:
id | user_id | image | tel
The question is how I can search the name of a user from profile?
$term = request()->term;
$profiles = Profile::with('user')->where('name', 'like', '%'.$term.'%')->get();
Then I want to show the profiles that their name comes from the search term.
use whereHas() ref link https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence
$term = request()->term;
$profiles = Profile::whereHas('user',function($q) use($term){
$q->where('name', 'like', '%' . $term . '%');
})->get();
$filterUser = function ($q) use ($term) {
$q->where('name', 'like', '%' . $term. '%');
};
$term = request()->term;
$profiles = Profile::whereHas('user', $filterUser)->with(['user'=> $filterUser])->get();
If you want to syntactically optimize the code and want to use this more often then add this method in model
public function scopeWithAndWhereHas($query, $relation, $constraint){
return $query->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}
And Usage:
$term = request()->term;
$profiles = Profile::withAndWhereHas('user', function($q) use ($term){
$q->where('name', 'like', '%' . $term. '%');
})->get();
You need to scope it on the subquery, something like this:
$profiles = Profile::with(['user' => function ($query) {
$query->where('name', 'like', '%'.$term.'%');
}])->get();
I'm building an application on Laravel 5.8 where I'm having a model named company, technical_description, state, region. A company can have many locations in many state, so company and state/region are having many-to-many relationship. So my model looks something like this:
class Company extends Model {
use SoftDeletes;
protected $guarded = [];
public function states()
{
return $this->belongsToMany('App\State', 'company_state', 'company_id', 'state_id');
}
public function regions()
{
return $this->belongsToMany('App\Region', 'company_region', 'company_id', 'region_id');
}
public function technicalDescription()
{
return $this->hasOne('App\TechnicalDescription', 'company_id', 'id');
}
}
I'm now building a data-table, where I'm having Company Name, Technical Details, State, Region as table headers. I want to sort according to these relationships, so I tried in controller:
public function companies() {
return CompanyResource::collection(
Company::when($request->name, function ($q) use($request) {
$q->where('name', 'like', '%' . $request->name .'%');
})
->join('company_technical_description', 'companies.id', '=', 'company_technical_description.company_id')
->when($request->sort_by_column, function ($q) use($request) {
$q->orderBy($request->sort_by_column['column'], $request->sort_by_column['order'] );
}, function ($q) use($request){
$q->orderBy('updated_at', 'desc');
})
->paginate();
)
}
So in this case if I want to sort with any details of technical description it will be easy by simply pushing company_technical_decription.established_date in $request->sort_by_column['column']
But in case of many-to-many relationship of state and region, I'm little stuck on how can I proceed.
Help me out with it. Thanks
I know way with join, worked for me with dynamic order for data tables.
You can try something like this:
public function companies() {
return CompanyResource::collection(
Company::when($request->name, function ($q) use($request) {
$q->where('name', 'like', '%' . $request->name .'%');
})
->select('companies.*', 's.name as state_name')
->join('company_technical_description', 'companies.id', '=', 'company_technical_description.company_id')
->join('company_state as cs', 'company_state.company_id', '=', 'companies.id')
->join('states as s', 'cs.state_id', '=', 's.id')
->when($request->sort_by_column, function ($q) use($request) {
$q->orderBy($request->sort_by_column['column'], $request->sort_by_column['order'] );
}, function ($q) use($request){
$q->orderBy('updated_at', 'desc');
})
->paginate();
)
}
I didn't test this solution but it's good for start. If you now pass state_name as argument for ordering, ordering should work. But I'm not sure in your database tables and columns so set your join to work.
I think it's good idea.
Good luck!
I have two models which linked with each other:
class Task extends Model{
public function user(){
return $this->belongsTo('App\User', 'user_id');
}
}
class User extends Model{
public function tasks(){
return $this->hasMany('App\Task', 'user_id');
}
}
Now I want to create some search or filter system.
There is a form where the user can choose Task only then the User's parameters (age, sex etc)
How can I do this kind of things? I tried to use newQuery on relation but...
Any help, thanks
I hope i understood you well.
Use nested where and whereHas as such
$tasks = Task::where('condition', $var)
->orWhereHas('user', function($q) use ($var){
$q->where('condition', 'LIKE', '%'. $var.'%');
});
try this. i hope it will work for you.
use join to get data from two tables
function getBuildings($request) {
if (isset($request->keyword) && $request->keyword != '') {
$data = $this->where(function($query) use ($request) {
$query->orWhere('users.column_name', 'LIKE', '%' . $request->keyword . '%');
$query->orWhere('users.column_name', 'LIKE', '%' . $request->keyword . '%');
});
}
$datacount = $this->count();
$dataArray = $this->select('users.*,task.whatever data you want to get from task');
if ($request->length == -1) {
$dataArray = $dataArray->get();
} else {
$dataArray = $dataArray->skip($request->start)->take($request->length)->get();
}
return [$datacount, $dataArray];
}
I have 2 tables
Entry
- id
- title
- submitter_name
- client_name
- agency_id
Agency
- id
- name
Entry Model
public function agency(){
return $this->belongsTo('App\Agency');
}
and Agency Model
public function entries(){
return $this->hasMany('App\Entry', 'entry');
}
I need to find all Entrys from database based on title,submitter_name,client_name,agency_name
The first 3 are easy
public function searchByData(Request $request) {
$Entrys = Entry::where('title', 'LIKE', '%'.$request->title.'%')
->where('submitter_name', 'LIKE', '%'.$request->submitter_name.'%')
->where('client_name', 'LIKE', '%'.$request->client_name.'%')
->get();
return view('entries.index')->with($Entrys);
But I'm failing miserably in finding Entries based on agency name.
try this:
public function searchByData(Request $request) {
$Entrys = Entry::where('title', 'LIKE', '%'.$request->title.'%')
->where('submitter_name', 'LIKE', '%'.$request->submitter_name.'%')
->where('client_name', 'LIKE', '%'.$request->client_name.'%')
->whereHas('agency, function($query) use($request){
$query->where('name', 'LIKE', '%' . $request->agency_name . '%');
})
->get();
return view('entries.index')->with($Entrys);
I have 3 models like this:
WarehousePivotCategory:
id - warehouse_id - warehouse_category_id
Warehouse:
title
WarehouseCategory:
title_en
I've created 2 hasOne relationships inside WarehousePivotCategory and they work fine:
public function Warehouse()
{
return $this->hasOne('App\Models\Warehouse','id','warehouse_id');
}
public function WarehouseCategory()
{
return $this->hasOne('App\Models\WarehouseCategory','id','warehouse_category_id');
}
in the database I have two records in warehouses table :
id title
1 AA
2 BB
I want to search title in warehouses :
$title = 'AA';
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%');
},'WarehouseCategory'])->get();
foreach ($warehouses as $w)
{
echo $w->warehouse->title; // no thing
}
but it doesn't return any of title of warehouses.
my relationships is correct because below code works fine :
WarehousePivotCategory::with('warehouse','WarehouseCategory')->paginate(10);
I think you're missing get method in your closure. Try it like this:
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%')->get(); },'WarehouseCategory'])->get();
You can also send array of fields you want to fetch to get method, like this:
$warehouses = WarehousePivotCategory::with(['warehouse' => function($q) use ($title) {
$q->where('title', 'like', '%' . $title . '%')->get(['id', 'title']); },'WarehouseCategory'])->get();
That is wrong. You don't need to use hasone while you have created pivot.You need to use BelongsToMany
class warehouse extends Model{
public function ware_cat(){
return $this->BelongsToMany('App\Models\WarehouseCategory');
}
public function getWarehouse(){
$this->with('ware_cat')->get();
}
}
Pivot table will fetch it so in warehouse model you will get its category and in category model you will get the warehouse same way visa-versa.