I want to keyword search from a table and its all related table using Elequent in Laravel5.
My controller is
$clients = Client::with('contacts', 'paymentTerm', 'addressInfo');
if ($q = Request::input("q")) {
$clients->where("clients.name", 'LIKE', "%$q%");
$clients->where("address_info.email", 'LIKE', "%$q%");//This is not working,I want to search from both client and client address_info
}
return $clients->paginate(10);
Client Model ,
public function addressInfo() {
return $this->hasOne('App\Model\ClientAddressInfo');
}
Client Address info,
public function client() {
return $this->belongsTo('App\Model\Client');
}
how can I apply keyword search here?
You can use whereHas to filter by a related model:
$clients->whereHas('addressInfo', function($query) use ($q){
$query->where("email", 'LIKE', "%$q%");
});
Related
I am implemeting a search using Laravel, but couldn't figure out how to get data from my pivot table. The pivot is a many to many relationship between Books and Tags.
The idea here is to search books by tags and display them.
class Book extends Model
{
public function tags() {
return $this->belongsToMany(Tag::class);
}
}
class Tag extends Model
{
public function books() {
return $this->belongsToMany(Book::class);
}
}
Other search seems to work just fine.
$books = Book::where('title', 'LIKE', '%'.$search_text.'%')
->orWhere('author', 'LIKE', '%'.$search_text.'%')
->orWhere('editor', 'LIKE', '%'.$search_text.'%')
->orWhere('ISBN', 'LIKE', '%'.$search_text.'%')
->orWhere('year', 'LIKE', '%'.$search_text.'%')
->orWhere('language', 'LIKE', '%'.$search_text.'%')
->get();
I am experimenting with creating a Restful API in Laravel and I am making use of the resources feature designed for API output. I have created the following models:
Book, Author and Category. I also created a resource for each of these models.
There is a one to many relationship between author and book and a many to many between category and book which has a pivot table.
I can return a collection of all books easily with the following:
return BookResource::collection(Book::with(['author', 'categories'])->paginate(10));
But I want to easily filter by author and category so I have implemented it in the following way inside my controller:
public function index(request $request)
{
//if no filer params are passed in return all books with author and categories
if (!$request->has('author') && !$request->has('category')) {
return BookResource::collection(Book::with(['author', 'categories'])->paginate(10));
}
//author param is passed in
if($request->has('author') && !$request->has('category')){
$authorName = $request->author;
return BookResource::collection(Book::whereHas('author', function ($query) use ($authorName) {
$query->where('name', $authorName);
})->get());
}
//category param is passed in
if(!$request->has('author') && $request->has('category')){
$categoryName = $request->category;
return BookResource::collection(Book::whereHas('categories', function ($query) use ($categoryName) {
$query->where('name', $categoryName);
})->get());
}
}
Is there a better more efficient way of returning the BookResource collection filtered by author and category?
Please try to implement this way. Hope this helps. Thanks.
public function index(){
$author = request ('author', null);
$category = request ('category', null);
$books = Book::with(['author', 'categories'])->when($author, function ($query) use ($author) {
return $query->whereHas('author', function ($query) use ($author){
$query->where('name', $author);
});
})->when($category, function ($query) use ($category) {
return $query->whereHas('categories', function ($query) use ($category) {
$query->where('name', $category);
});
})->paginate(10);
return BookResource::collection($books);
}
I have a model Job which is attached to one model Project.
Here are the class definitions:
class Job extends Model
{
public function project() {
return $this->belongsTo('App\Project');
}
}
class Project extends Model
{
public function jobs() {
return $this->hasMany('App\Job');
}
}
I'm trying to query the Jobs collection and filter on either jobs.title or project.title.
Here is my current search query:
$jobs = Job::where(function($query) use ($searchTerm) {
$query->where('title', 'LIKE', $searchTerm)
->orWhereHas('project', function ($subQuery) use ($searchTerm) {
return $subQuery->where('title', 'LIKE', $searchTerm);
});
})->get();
However, this is returning an error:
Call to undefined method Jenssegers\Mongodb\Query\Builder::getHasCompareKey()
I think you need to clean up your code a bit:
$jobs = Job::where('title', 'LIKE', $searchTerm)
->orWhereHas('project', function ($query) use ($searchTerm) {
$query->where('title', 'LIKE', $searchTerm);
})->get();
I have four models: OwnerCompany, Owner, User, and Role.
I want to get all OwnerCompanys eager loading their Owner and also eager loading its Users who have the Role with the name 'admin'.
OwnerCompany::with('owner.users')->whereHas('owner.users.roles', function ($query) {
$query->where('name', 'admin');
})->get();
This loads in the models but doesn't constrain the users, they are all loaded.
Not tested . I think you are missing like or equal operator.
OwnerCompany::with('owner.users')->whereHas('owner.users.roles', function ($query) {
$query->where('name','like','admin');
})->get();
I try this, if work then let me know. not tested
1).
OwnerCompany::with('owner.users.roles')->whereHas('owner', function ($query) {
$query->whereHas('users', function($qr){
$qr->whereHas('roles', function($q){
$q->where('name', 'admin');
});
});
})->get();
OR
2).
OwnerCompany::with('owner.users.roles')->whereHas('owner.users.roles', function ($query) {
$query->where('name', 'admin');
})->get();
If I got it right, you want each OwnerCompany object to contain the Owner object, which will contain "admins". I would do something like this.
$ownerCompany = OwnerCompany::all();
return $ownerCompany->each(function ($company) {
$company->owner;
$company->owner->users->each(function ($user) {
return $user->hasRole('admin');
});
});
and inside User class:
public function role()
{
return $this->belongsTo(Role::class);
}
public function hasRole($role)
{
if ($this->role()->where('name', $role)->first()) {
return $this;
}
return null;
}
Unfortunately, I can't test it right now, so If you have any trouble let me know.
I am trying to do a query that filters on 2 columns on one table OR 2 columns on another. This is what I have so far:
// In my controller
return $registry = Registry::search($first_name, $last_name)->get();
// In my model
public function user()
{
return $this->belongsTo('User');
}
public function scopeSearch($query, $first_name, $last_name)
{
$search = $query->where('coregistrant_first_name', 'LIKE', "%$first_name%")
->where('coregistrant_last_name', 'LIKE', "%$last_name%")
->orWhere(function($query) use ($first_name, $last_name)
{
$query->$this->user()->where('first_name', 'LIKE', "%$first_name%");
});
return $search;
}
I have tried a lot of different things and now I'm stuck on the $query->$this->user() line with this error:
Undefined property: Illuminate\Database\Query\Builder::$[]
Anyone know how I can fix this problem?
#Keith, In Laravel, you can not use relationship for selecting data dynamically.
AS far as i know, Laravel support the following rules to retrieve data using relationship:
$registers = Registry::with('user')->get();
$registers = Registry::where('xyz', '1')->get();
// then you can load the relationship if you needed
$registers->load('user');
In your model
public function user()
{
return $this->belongsTo('User')->where('first_name', 'LIKE', "%xyz%");
}
Then From your controller:
$registers = Registry::with('user')->get();
If you have one to many relationship,
Say you have licenses relationship
// You can specify an operator and a count:
$registers = Registry::has('licenses', '>=', 3)->get();
Reference: http://laravel.com/docs/eloquent#querying-relations
I ended up using query builder to do it.