I have a table with input fields that act as filters. There are values from Orders table and Users table which has a relationship.
e.g.:
Order Id | User Full Name | Order Price | Date |
[order filter] [user name filter] [order date filter]
How can I filter a value from a users table via relationship?
This returns error of course:
public function name($name)
{
return $this->builder->where('name', 'LIKE', '%$name%')->orWhere('surname', 'LIKE', '%$name%');
}
Error:
QueryException in Connection.php line 770:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'name' in 'where clause' (SQL: select count(*) as aggregate from `orders` where (`name` LIKE %$name% or `surname` LIKE %$name%))
You can add the condition directly to your query builder or create a scope.
Add this to your Order model.
public function scopeFilterUser($query, $name)
{
return $query->whereHas('user', function ($q) use ($name) {
$q->where('name', 'like', "%{$name}%")
->orWhere('surname', 'like', "%{$name}%");
});
}
Use it like so
$orders = Order::filterUser($name)->get();
Apply the condition directly.
$orders = Order::whereHas('user', function ($query) use ($name) {
$query->where('name', 'like', "%{$name}%")
->orWhere('surname', 'like', "%{$name}%");
})->get();
Edit : Based on your filter methods.
public function name($name)
{
return $this->builder->whereHas('user', function ($q) use ($name) {
$q->where('name', 'like', "%{$name}%")
->orWhere('surname', 'like', "%{$name}%");
});
}
Related
I have these tables:
user_points
- user_class_id
- scoreable_id
-scoreable_type
points_interaction_system
- user_id
- points
- type
supplementary_assessments
- user_id
- points
In user_points table the scoreable_type will receive the model of the one of the other tables like App\Models\SupplementaryAssessment or App\Models\PointInteractionSystem and the scoreable_id the id of the model.
What i want to do is join the supplementary table records only with the rows in the user_points that have in the scoreable_type the model SupplementaryAssessment and join the points_interaction_system records only the rows in the user_points that have in the scoreable_type the model PointInteractionSystem. At the end i want sum all the points fields based on the user id.
I did something like this, but its not working:
DB::table('user_points')
->join('user_classes', function ($join) use ($user) {
$join->on('user_points.user_class_id', '=', 'user_classes.id')
->where('user_classes.user_id', $user->id);
})
->leftJoin('supplementary_assessments', function ($join) {
$join->on('user_points.scoreable_id', '=', 'supplementary_assessments.id')
->where('user_points.scoreable_type', 'like', '%SupplementaryAssessment');
})
->leftJoin('points_interaction_system', function ($join) {
$join->on('user_points.scoreable_id', '=', 'points_interaction_system.id')
->where('user_points.scoreable_type', 'like', '%PointInteractionSystem');
})
->get();
Try something like:
DB::table('user_points')
->join('user_classes', function ($join) use ($user) {
$join->on('user_points.user_class_id', '=', 'user_classes.id')
->where('user_classes.user_id', $user->id);
})
->join('supplementary_assessments', function ($join) {
$join->on('user_points.scoreable_id', '=', 'supplementary_assessments.id')
->where('user_points.scoreable_type', 'like', '%SupplementaryAssessment%');
})
->join('points_interaction_system', function ($join) {
$join->on('user_points.scoreable_id', '=', 'points_interaction_system.id')
->where('user_points.scoreable_type', 'like', '%PointInteractionSystem%');
})
->get();
Uses join instead of left-join.
I want to apply search on the item members which is associated with the item.
I've members relation on my Item model like this
public function members()
{
return $this->hasManyDeep(
'App\Models\Users\TeamMember',
['App\Models\Users\Team'],
[['teamable_type', 'teamable_id'], 'team_id'],
['id', 'id']
);
}
I've done this code for apply search on items on the bases of item's members
$items = Item::query();
->where('title', 'Like', '%' . $keyword . '%')
->with('members')
->orWhereHas('members', function ($query) use($keyword) {
$query->from('users')->where('name', 'Like', '%' . $keyword . '%');
})->get();
this relation will be return an array of members. Now It's giving me error called -
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'team_members.team_id' in 'on clause' (SQL: select * from `items` and `title` Like %test% or exists
I have assigned search method for my application and i have made relationship between two tables "users " table and "posts" table both of them have same field name "created_at" and when i want to fetch data that when this post has been created it will bring the date in users table created_at field not in posts table created_at field.
All i want is how to tell the system make difference between which table field name i mean .
This date comes from created_at field in users table
I wand to come date in this created_at field in posts table
ListingController.php
public function search(Request $request){
$posts = Post::with(['comments','category','creator'])
->join('users', 'posts.created_by', '=', 'users.id')
->where('slug', 'LIKE', '%'.$request->search. '%')
->orWhere('users.name', 'LIKE', '%'.$request->search. '%')
->where('status',1)->orderBy('posts.id','DESC')->paginate(5);
return view('front.listing',compact('posts'));
}
listing.blade.php
<div class="article_date">
by: {{ $post->creator->name }} , {{$post->created_at->diffForHumans()}}
</div>
You are calling your relationship improperly. You should not use a join there. Use constrained eager loading instead
There will be no conflict in the created_at date since there will be no join.
While still keeping your search query inside the closure of the relationship.
$posts = Post::with(['comments', 'category'])
->with(['creator' => function ($query) use ($request) {
$query->where('name', 'LIKE', '%' . $request->search . '%');
}])
->where('slug', 'LIKE', '%' . $request->search . '%')
->where('status', 1)
->orderBy('id', 'DESC')
->paginate(5);
I'm building an application on Laravel, where I'm having Project and LatestStatus model, I've a table which has sorting facilities. So I can sort by name, its latest-status, last updated by etc. So the architecture of this is:
projects
id
name -> string
state -> string
region -> string
status -> enum ('saved', 'draft')
created_at -> timestamp
updated_at -> timestamp
project_latest_status
id
project_id -> integer // (project id foreign key)
status -> string // (current status of project)
I want to sort projects by joining the latest_status table and sort according to current status of project. For this I tried something like this:
Project::where('status', 'saved')
->when( $request->name , function( $q) use( $request ) {
$q->where('name', 'like', '%' . $request->name .'%');
})
->when($request->status, function ($q) use($request) {
$q->whereHas('latestStatus', function ($q) use($request){
$q->whereHas('status', function ($q) use($request) {
$q->whereIn('name', collect($request->status)->pluck('name') );
});
});
})
->when($request->sort_by_column, function ($q) use($request) {
$q->when($request->sort_by_column['column'] == 'name' || $request->sort_by_column['column'] == 'website', function ($q) use($request) {
$q->orderBy($request->sort_by_column['column'], $request->sort_by_column['order'] );
})
->when($request->sort_by_column['column'] == 'added_date' , function ($q) use ($request) {
$q->orderBy('created_at', $request->sort_by_column['order']);
})
->when($request->sort_by_column['column'] == 'status', function ($q) use ($request) {
$q->join('project_latest_status', 'projects.id', '=', 'project_latest_status.project_id')
->join('project_status', 'project_latest_status.status', '=', 'project_status.id')
->select('projects.*', 'project_status.name as status_name')
->orderBy('status_name', $request->sort_by_column['order']);
})
})->get();
Everything works fine but as soon as I click on status sort it gives me an error:
SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'status' in where clause is ambiguous (SQL: select count(*) as aggregate from projects inner join project_latest_status on projects.id = project_latest_status.project_id inner join project_status on project_latest_status.status = project_status.id where status = saved and projects.deleted_at is null)"
Help me out in this. Thanks
change where from
where('status', 'saved')
to
where('projects.status', 'saved')
or where ever you use status with another join table another same field so you need to specify the table where you want to filter by status
I have a table named records with a user_id column which links to a users table to set ownership.
I can correctly filter the records by title with a search string:
$records->where('title', 'LIKE', '%'.$search.'%');
But I'd like to return also the results containing the users.firstname and users.lastname, this is my (awful) join attempt:
$records->join('users', 'users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%')
->orWhere('title', 'LIKE', '%'.$search.'%');
// SQLSTATE[23000]: Integrity constraint violation: 1052 Column 'id' in order clause is ambiguous
While I wait for a better answer I found a solution which works but it's not optimal since it involves one extra query to gather the author user_id and use it subsequently to query the records:
// Get the author ID
$author = DB::table('users')
->select(DB::raw('CONCAT_WS(" ",`firstname`,`lastname`) as `fullname`,id'))
->having('fullname', 'LIKE', '%'.$search.'%')
->first();
// $author output:
stdClass Object
(
[fullname] => John Doe
[id] => 35
)
// Query the records using the gathered ID
$records->where('user_id', $author->id)
->orWhere('title', 'LIKE', '%'.$search.'%');
Problems with this solution: Apart from the extra query, if somebody searches for John Doe or Some Title the results are correct. But if searching for John Doe Some Title, nothing is shown because the author and the title can't be found.
You need to set that also use the search parameter in your inner query:
$records->join('users', function($join) use ($search)
{
$join->on('users.id', '=', 'records.user_id')
->where('users.firstname', 'LIKE', '%'.$search.'%')
->orWhere('users.lastname', 'LIKE', '%'.$search.'%');
});
If I understand you want to return result from Records by filtering with $search and also want to show users info for this records.
You can use Eloquent.
Your model must be:
In User model:
public function records()
{
return $this->hasMany(Record::class);
}
In Record model:
public function user()
{
return $this->belongsTo(User::class);
}
And in Controller:
Record::where('title', 'LIKE', '%'.$search.'%')
->with('user')
->first();