How to convert database query builder into Eloquent models - php

I need to convert a database query builder into an Eloquent model. I'm using the plugin https://github.com/Kyslik/column-sortable and it requires an Eloquent model.
<?php
$payments = DB::table('users')
->select('orders.id', 'users.id', 'users.name', 'orders.amount', 'orders.created_at', 'orders.updated_at')
->join('patients', 'users.id', '=', 'patients.user_id')
->join('orders', 'patients.id', '=', 'orders.patient_id')
->where('users.name', 'LIKE', '%' . $q . '%')
->orWhere('users.email', 'LIKE', '%' . $q . '%')
->get();

call your model inside your controller method.
$companyObj = new modelname();
$userDetail = $companyObj->model_method_name($request);

try declaring eloquent relationship in your respective model as given below:
class Users extends Model {
public function patients(){
return this->hasOne('App\Patients', 'user_id', 'id')->with('orders');
}
}
class Patients extends Model {
public function orders() {
return this->hasMany('App\Orders', 'patient_id', 'id')->select('id', 'amount', 'created_at', 'updated_at');
}
}
now call these relationships in eloquent query in Users repository/controller:
$payments = $this->getModel()->select('id', 'name')->with('patients')->where('name','LIKE','%'.$q.'%')->orWhere('email','LIKE','%'.$q.'%')->get();

Related

Relation query undefined method

In my setting model class i have this
public function user()
{
return $this->hasMany('App\User');
}
and in my user model class i have this
public function settings()
{
return $this->belongsTo('App\settings', 'id');
}
I tried both these queries, trying to get the user information but failed.
$data = DB::table('settings')
->where('id', '=', $id)
->get()
->toArray();
and
$table = \App\settings::where('id', '=', $id);
$query = $table->user()
->get()
->toArray();
I'm getting this error
Call to undefined method Illuminate\Database\Eloquent\Builder::user()
How do you do relation query? Sorry new to laravel here.
$table = \App\settings::where('id', '=', $id)->first();
$query = $table->user->toArray();
Eager load
$table = \App\settings::with('user')->where('id', '=', $id)->first();
$query = $table->user->toArray();

Search Data from multiple tables laravel

I am trying to search multiple data from two related tables. To be specific I want to get only "name column" from the users table and the rest of the columns from the posts table. But whenever I tried to search it prints the following error "Trying to get property 'name' of non-object"
Below is my user model
<?php
namespace App;
use App\Mail\NewUserWelcomeMail;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Support\Facades\Mail;
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'name', 'email','phone', 'username', 'password',
'admin', 'address', 'description', 'approved_at',
];
protected $hidden = [
'password', 'remember_token',
];
public function posts()
{
return $this->hasMany(Post::class)->orderBy('created_at', 'DESC');
}
}
And post model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $guarded = [];
public function user()
{
return $this->belongsTo(User::class);
}
}
And my Controller
public function showcampaign(User $user) {
$q = Input::get( 'q' );
if( !empty( $q ) ) {
$showcampaign = User::join('posts','posts.user_id','users.id')
->where('name','LIKE','%'.$q.'%')
->orWhere('caption','LIKE','%'.$q.'%')
->orWhere('description','LIKE','%'.$q.'%')
->orWhere('duration','LIKE','%'.$q.'%')
->orWhere('amount','LIKE','%'.$q.'%')
->get();
if(count($showcampaign) > 0) {
return view('admin.campaignreport', ['show' => $showcampaign]);
} else {
return redirect('/campaignreport')->with('status', 'No Details found. Try to search again !');
}
} else {
$showcampaign = Post::all();
return view('admin.campaignreport')->with('show', $showcampaign);
}
}
Please help thanks
As you have already declared the relations within the Model So you can use whereHas and also orWhereHas
So
$showcampaign = SampleReception::query()
->whereHas('posts',function(\Illuminate\Database\Eloquent\Builder $query) use ($q){
return $query->where('caption', 'LIKE','%'.$q.'%')
->orWhere('description', 'LIKE','%'.$q.'%')
->orWhere('duration', 'LIKE','%'.$q.'%')
->orWhere('amount', 'LIKE','%'.$q.'%');
})
->orWhere('name','LIKE','%'.$q.'%')
->get();
For any issues leave a comment
Try.. use where instead of orwhere
$showcampaign = User::join('posts','posts.user_id','users.id')
->where('name','LIKE','%'.$q.'%')
->Where('caption','LIKE','%'.$q.'%')
->Where('description','LIKE','%'.$q.'%')
->Where('duration','LIKE','%'.$q.'%')
->Where('amount','LIKE','%'.$q.'%')->get();
I think you need to use a reference table for where clause.
$showcampaign = User::join('posts','posts.user_id', '=', 'users.id')
->where('users.name','LIKE', '%'.$q.'%')
->orWhere('posts.caption', 'LIKE','%'.$q.'%')
->orWhere('posts.description', 'LIKE','%'.$q.'%')
->orWhere('posts.duration', 'LIKE','%'.$q.'%')
->orWhere('posts.amount', 'LIKE','%'.$q.'%')
->get();
If you define relationship correctly then use:
$showcampaign = SampleReception::with(['posts' => function($query) use($q) {
return $query->where('caption', 'LIKE','%'.$q.'%')
->orWhere('description', 'LIKE','%'.$q.'%')
->orWhere('duration', 'LIKE','%'.$q.'%')
->orWhere('amount', 'LIKE','%'.$q.'%');
}])
->orWhere('name','LIKE','%'.$q.'%')
->get();
I use scope query to create search functions. It makes my code more flexible and easy to understand.
Here is how you can do this.
In your "user" Model, you have to write "scopeFunctionName". you can write any functionName with scope. And in your Controller, you can simply call this function whenever you need as functionName(). and pass here your search term from request as functionName(request(['search']))
And now as you have declared relations for these tables to search data from related tables, try using this code in your user Model
public function scopeFilter($query, array $filters)
{
/*
Hey $query! whenever u get 'search term' in URL, call the function.
If ['search'] exists or != null, then pass its value to the function
else return false and don't execute the $query. If value exists,
Then the function will execute the query and returns a result.
*/
$query->when(
$filters['search'] ?? false,
fn ($query, $search) =>
$query
->whereHas('users', function ($query) use ($search) {
return $query
->where('name', 'like', '%' . $search . '%')
})
->where('name', 'like', '%' . $search . '%')
->orWhere('caption', 'like', '%', . $search . '%')
->orWhere('description', 'like', '%', . $search . '%')
->orWhere('id', $search)
);
}
And in Controller, you can pass the value to the scope function as:
public function index()
{
return view('posts.index', [
'show' => Post::all()->filter(request(['search']))->with('user')
]);
}
Note: The code above has not been tested but it might solve your problem.

How can I get data when I search using relationship eloquent laravel

How to get value relationships in eloquent laravel
here is my model Food
class food extends Model
{
protected $table = 'food';
protected $fillable = [
'name'
];
public function foodType()
{
return $this->belongsTo(Food_type::class, 'food_type_id');
}
}
here is my food_type model
class food_type extends Model
{
protected $table = 'food_type';
protected $fillable = [
'name', 'description'
];
public function getFood()
{
return $this->hasMany(Food::class);
}
}
I want to get food_type.name in food_type table .How can I query like this
$search = $request->search
$food = Food::with(['foodType'])
->where('name', 'like', '%'.$search.'%')
->orWhere('foodType.name', 'like', '%'.$search.'%')->get();
Relationships are not included with joins when you use eager loading. Review the documentation as it covers how to use whereHas and other relationship related methods.
$food = Food::with(['foodType'])
->where('name', 'like', '%'.$search.'%')
->orWhereHas('foodType' function($q) {
$q->where('name', 'like', '%'.$search.'%');
})
->get();

How to select some field and order by on Querying Relationship Existence? Laravel 5.3

My code is like this :
public function getFavoriteStore($param)
{
$num = 20;
$q = $param['q'];
$location = $param['location'];
$result = $this->store_repository->whereHas('favorites', function ($query) use($q, $location) {
$query->select('stores.id', 'stores.name', 'stores.photo','stores.address')
->where('stores.status', '=', 1)
->where('favorites.favoritable_type', 'like', 'App\\\Models\\\Store');
if($location)
$query->where('stores.address', 'like', "%$location%");
if($q) {
$query->where('stores.name', 'like', "%$q%")
->where('stores.address', 'like', "%$q%", 'or');
}
$query->orderBy('favorites.updated_at', 'desc');
})->paginate($num);
return $result;
}
It works
But, order by does not work
Besides, the above query, I only select some field. But when I debug the query, the result display all field
It seems there are still wrong
Is there anyone who can help me?
I follow this tutorial : https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-existence
UPDATE
My favorite model is like this :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Favorite extends Model
{
protected $fillable = ['user_id', 'favoritable_id', 'favoritable_type'];
public function favoritable()
{
return $this->morphTo();
}
}
My store model is like this :
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Store extends Model
{
protected $fillable = ['name', 'address', 'phones', 'address', 'email'];
public function favorites()
{
return $this->morphMany(Favorite::class, 'favoritable');
}
}
Favorites table has field id, user_id, favoritable_id, favoritable_type
Stores table has field id, name, address, phones, addres, email, photo
The relation between store and favorite are id (stores table) and favoritable_id (favorites table)
whereHas() is only used to check the existence of a relation so, you have to use join() to order the results with related table
$query = $this->store_repository
->join('favorites', function ($join) {
$join->on('stores.id', '=', 'favorites.favoritable_id')
->where('favorites.favoritable_type', 'like', 'App\\\Models\\\Store');
})
->where('stores.status', '=', 1)
->select('stores.id', 'stores.name', 'stores.photo','stores.address');
if($location)
$query->where('stores.address', 'like', "%$location%");
if($q) {
$query->where('stores.name', 'like', "%$q%")
->where('stores.address', 'like', "%$q%", 'or');
}
$result = $query->orderBy('favorites.updated_at', 'desc')->paginate($num);
I have not tested it but I am pretty sure it will work.

Laravel 5 nested search query

I'm trying to make a nested search query but I get this error. I'm trying to search for a company name joined by a company_id.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'company.name' in 'where clause' (SQL: select count(*) as aggregate from `position` where `to_date` >= 2016-06-16 and `company_id` = 123795854693734 and `title` like %searchquery% and `company`.`name` like %searchquery% and `location` like %%)
Here is my controller function
public function Search(){
$keyword = Input::get('q');
$location = Input::get('l');
$data = Position::where('to_date', '>=', date('Y-m-d'))
->where('company_id', '=', $company_id)
->where('title', 'like', '%'.$keyword.'%')
->where('company.name', 'like', '%'.$keyword.'%')
->where('location', 'like', '%'.$location.'%')
->orderBy('from_date', 'desc')
->paginate(10);
$data = array(
'data' => $data,
);
return view('myview', $data);
}
The model works perfectly. But here it is anyway.
namespace App;
use Illuminate\Database\Eloquent\Model;
class Position extends Model {
protected $table = 'position';
protected $guarded = array("id");
protected $hidden = array();
protected $appends = array('local_ad');
protected $fillable = ['title', 'company_id', 'location'];
public function company() {
return $this->belongsTo('App\Company', 'company_id', 'id');
}
}
You are not using your relation or joining to the company table actually, that's why it can't find it.
Simply, you can use whereHas method to filter positions with company names.
$data = Position::whereHas('company', function ($q) use ($keyword) {
$q->where('name', 'like', '%'.$keyword.'%');
})->where('to_date', '>=', date('Y-m-d'))
->where('company_id', '=', $company_id)
->where('title', 'like', '%'.$keyword.'%')
->where('location', 'like', '%'.$location.'%')
->orderBy('from_date', 'desc')
->paginate(10);
This function should be
public function Search(){
$keyword = Input::get('q');
$location = Input::get('l');
$data = Position::where('to_date', '>=', date('Y-m-d'))
->where('company_id', '=', $company_id)
->where('title', 'like', '%'.$keyword.'%')
->with(['company' => function( $q ) use ($keyword) {
->where('name', 'like', '%'.$keyword.'%')
}])
->where('location', 'like', '%'.$location.'%')
->orderBy('from_date', 'desc')
->paginate(10);
$data = array(
'data' => $data,
);
return view('myview', $data);
}
but this does not do a join, this will fetch position, there is a whereHas in Eloquent, you should explore that also.

Categories