How to set Where condition in my model definition in laravel - laravel

MY model works perfectly:
class Customer extends Model
{
/**
* #var string The database table used by the model.
*/
public $table = 'users';
/**
* #var array Validation rules
*/
public $rules = [
];
public $hasMany = [
'voucher' => ['ItScholarBd\Api\Models\Voucher']
];
}
This Customer model refers to users table. all users having role_id=5 is only customers. So this Model will always fetch users data where role_id = 5. I can achieve this as usual practice. But is there any smart way to set this where clause inside this Model so that Customer model always fetch user data having role_id = 5. i.e: Customer::get(); will return users where role_id = 5

Add following method in your customer model.
public function scopeCustomers($query)
{
return $query->where('role_id', 5);
}
and fetch records like this:-
$customers = Customer::customers();

Related

Laravel Eloquent relationship data retrieve

I have below code to get data from database,
$profile = Profiles::find(1);
$currency = Profiles::find($profile->currency_id)->currency;
Then created a relationship in the model as below,
class Profiles extends Model
{
use HasFactory;
protected $table = 'Profiles';
protected $primaryKey = 'profile_id';
public function Currency()
{
return $this->belongsTo(Currencies::class, 'currency_id');
}
}
class Currencies extends Model
{
use HasFactory;
protected $table = 'Currencies';
protected $primaryKey = 'currency_id';
public function profile()
{
return $this->hasOne(Profiles::class, 'currency_id');
}
}
Problem is that there is only 1 profile and 100 currency, currency_id is a foreign key in Profiles table,
I could not get data and get this error, Trying to get property 'currency' of non-object"
If i use $currency = Profiles::find(1)->currency; then it retrieve first row of Curriencies table which is not required data.
How can I get currency row for that specific profile?
The problem is that the find() method will look for the primaryKey and in your second call the currency_id is not the pk.
Two solution for you:
replace the find by a where clause like so: $currency = Profiles::where('currency_id',$profile->currency_id)->value('currency')
Or a more Laravel way to do it, through the relationship $currency = $profile->currency;

Laravel Eloquent How Can I Select Using Condition "where" for pivot table

I have three database tables called user(id,name), group(id,name) and user_group(user_id, group_id,valid_before) with relations many to many.
class User extends Model
{
protected $table = 'user';
public function groups()
{
return $this->belongsToMany(Group::class, 'user_group')
->withPivot('valid_before');
}
}
class Group extends Model
{
protected $table = 'group';
public $timestamps = false;
public function user()
{
return $this->belongsToMany(User::class, 'user_group');
}
}
How can I select all users (using Eloquent) who have
valid_before < $some_date
?
There are many ways to achieve this goal. I'll show you an example using query scopes.
In your User class you have to make a little update:
class User extends Model
{
protected $table = 'user';
public function groups()
{
return $this->belongsToMany(Group::class, 'user_group')
//->withPivot('valid_before'); <-- Remove this
}
}
and create a scope in your Group model:
class Group extends Model
{
protected $table = 'group';
public $timestamps = false;
public function user()
{
return $this->belongsToMany(User::class, 'user_group');
}
/**
* This scope gets as input the date you want to query and returns the users collection
*
* #param \Illuminate\Database\Eloquent\Builder $query
* #param string $date
* #return \Illuminate\Database\Eloquent\Builder
*/
public function scopeUsersValidBefore($query, $date)
{
return $query->users()->wherePivot('valid_before', '<', $date);
}
}
Now, I imagine you have a GroupController that somewhere creates a query to retrieve the valid before users. Something like:
// [...]
$users = Group::usersValidBefore($yourDate)->get();
// [...]
If you want to create the query from the other side, I mean you want to use the User model and list all the Users that has a pivot relation with valid_before populated, than the right approach is creating a UserGroup intermediate model that can be easily used to create a query.
If you are using Laravel 8.x.x
It's much easier with Inline Relationship Existence Queries
If you would like to query for a relationship's existence with a single, simple where condition attached to the relationship query, you may find it more convenient to use the whereRelation and whereMorphRelation methods. For example, we may query for all posts that have unapproved comments:
use App\Models\Post;
$posts = Post::whereRelation('comments', 'is_approved', false)->get();
Of course, like calls to the query builder's where method, you may also specify an operator:
$posts = Post::whereRelation(
'comments', 'created_at', '>=', now()->subHour()
)->get();

Laravel: Multiple tables in one model

I have the following model for Users:
class User extends Authenticatable
{
use Notifiable;
protected $table = 'login_info';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getDashboards()
{
return \DB::table('dashboard')
->select('type')
->where('id', Auth::id())
->orderBy('column', 'asc')
->get();
}
}
Users have different information in many tables
user info like name, office, dashboard,2FA etc
Is the way I do it now "best practice" (like the getDashboards function) for getting information from different tables?
Or should I create a model for each of the tables and then "join them" (hasMany, belongsToMany, and so on) for each of the tables?
EDIT:
I am now using models, but the result of the query is always an empty array.
class Dashboard extends Model
{
protected $table = 'dashboard';
public function user()
{
return $this->belongsTo(User::class,'user_id','id');
//user_id
}
}
user_id is the id of the user which is used in the login_info table.
And in the User class I have:
public function dashboards()
{
return $this->hasMany(Dashboard::class,'id','user_id');
}
In the login controller I have:
$user = \App\User::find(1);
$user->dashboards;
Anyone see what the problem could be?
Thanks for any help!
public function dashboards()
{return $this->hasMany(\App\Dashboard::class);
}
And in your Dashboard Model you do it this way
protected $casts = [
'user_id' => 'int',
];
public function user()
{
return $this->belongsTo(\App\User::class);
}
The more Laravel way is to rather created the related Dashboard model and use the eloquent relationships, and harness the features of the ORM. Nothing wrong to include an orderBy on the relationship if you always need ordering on that column.
class User extends Authenticatable
{
public function dashboards()
{
return $this->hasMany(Dashboard::class)
->orderBy('column', 'asc');
}
}
class Dashboard extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
}
You do not have to do anything in the model! Just refer to the model in the controller, for example:
User::where('id', Auth::id())->pluck('type');

Laravel Relation Query

I have two tables course and module where each course belongs to a single module.
What I need is to eager load the module with course
my codes is :
$courses = Course::all();
$module = Coursemdule::all();
You need to create relation between both the table
In the course model
/**
* Get the user that owns the phone.
*/
public function module()
{
return $this->belongsTo('App\Coursemdule');
}
In the Coursemdule model
/**
* Get the Course record associated with the Coursemdule.
*/
public function course()
{
return $this->hasOne('App\Course');
}
To fetch this value
$phone = Course::find(1)->module;
OR
$phone = Course::with('module')->all();
I hope this will help you.

Displaying users with 2 related tables records

I have 3 Models :
User, Role and Branch.
They are related like this :
Pour User model :
class User extends Model
{
// Define fields to be fillable
protected $fillable = [
'firstname',
'lastname',
'telephone',
'address',
'password',
'code',
'status',
'branches_id',
'roles_id'
];
/**
* Get the role record associated with the user.
*/
public function role()
{
return $this->hasOne('App\Role');
}
/**
* Get the branch record associated with the user.
*/
public function branch()
{
return $this->hasOne('App\Branch');
}
}
For Role Model :
class Role extends Model
{
// Define fields to be fillable
protected $fillable = ['description'];
/**
* Get the user that owns the role.
*/
public function user()
{
return $this->belongsToMany('App\User');
}
}
For branch model :
class Branch extends Model
{
// Define fields to be fillable
protected $fillable = ['description', 'location'];
/**
* Get the user that owns the branch.
*/
public function user()
{
return $this->belongsToMany('App\User');
}
}
I know that if i was using Blade, to list user's roles, i could have done something like : $user->role()
But i am trying to use angular 2 for the frontend and laravel 5.3 for my backend.
My question is how to retrieve users along with roles and branches
Here is my index action in my UserController:
public function index()
{
// Get all users, along with roles and branches
$users = User::all();
// Send the response
return response()->json([
'users' => $users
], 200);
}
Use eager loading:
$users = User::with('role', 'branch')->get();
Also if user has one role and one branch, relationships should be belongsTo() instead of belongsToMany():
return $this->belongsTo('App\User');
You can use the with() method for this, e.g.
$users = User::with('role')->get();
See https://laravel.com/docs/5.4/eloquent-relationships#eager-loading for more information

Resources