I have a Model called User with stuff like name, country and some relationships.
Now I want a Model, e.g. Vendor, having all the same functions and variables as a User including some More stuff
I thought I could to it this was:
class User extends Model implements AuthenticatableContract
{
use Authenticatable; SoftDeletes;
protected $dates = ['deleted_at', 'last_login'];
protected $fillable = [
'name',
'password',
'country',
];
protected $hidden = ['password'];
public function logs()
{
return $this->hasMany('App\Log');
}
}
And the Vendor Model:
class Vendor extends User
{
protected $fillable = [
'description'
];
public function user() {
return $this->belongsTo('App\User');
}
public function products()
{
return $this->hasMany('App\Product', 'vendor_id');
}
The Controller checks the role of the user and loads a user model or a vendor model:
if(Auth::user()->role > 1)
$user = Vendor::where('user_id', Auth::user()->id)->first();
else
$user = Auth::user();
return $user->load('logs');
But the load call fails for a vendor. I was able to join the fields of a user inside a vendor but I also need the functions of it.
The problem was that the logs function checks a field that doesn't exists.
Using this functions works:
public function logs()
{
return $this->hasMany('App\Log', 'user_id', get_called_class() !== get_class() ? 'user_id' : 'id');
}
Related
I have 3 models
User - Role- Permission
User
class User extends Model
{
protected $fillable = [
'name', 'email', 'password',
];
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
Role
class Role extends Model
{
protected $fillable = ['name' , 'label'];
public function users()
{
return $this->belongsToMany(User::class);
}
public function permissions()
{
return $this->belongsToMany(Permission::class);
}
}
Permission
class Permission extends Model
{
protected $fillable = ['name' , 'label'];
public function roles()
{
return $this->belongsToMany(Role::class);
}
}
I want get List of users whose permissions were updated on a specific date
I know I sould use something like below but I dont know exatly how to use Where
$users = User::with('roles.permissions')->orderBy('name', 'asc')->paginate(25);
thanks alot
Use whereHas():
$users = User::whereHas('roles.permissions', function($query) use($date) {
$query->whereDate('permission_role.updated_at', $date);
})->orderBy('name', 'asc')->paginate(25);
I have 2 models. The User model, and the relationship works correctly, I use tinker, and I can see the application that is associated with the user.
User::find(4)->application
However, the application will not return the user - in tinker I get null, whats worse, if I try to access rep in tinker, I get Bad Method Exception Call
Application::find(8)->user
is null
Note: I have an id column in users which I "find" users. and there is "ucid" column in users that I have defined as the primaryKey in Application.
Application Model:
class Application extends Model
{
protected $data = [
'data' => 'array'
];
protected $primaryKey = 'ucid';
protected $fillable = [
'ucid', 'data'
];
public function user()
{
return $this->belongsTo(User::class,'ucid');
}
public function rep()
{
return 'Test';
}
}
User Model
class User extends Authenticatable
{
public function application()
{
return $this->hasOne(Application::class,'ucid');
}
}
What am I missing?
Can you try this? Let me know if it works..
Application Model
class Application extends Model
{
protected $data = [
'data' => 'array'
];
protected $primaryKey = 'ucid';
protected $fillable = [
'ucid', 'data'
];
public function user()
{
return $this->hasOne(User::class, 'ucid');
}
public function rep()
{
return 'Test';
}
}
User Model
class User extends Authenticatable
{
public function application()
{
return $this->belongsTo(Application::class, 'ucid', 'ucid');
}
}
As you see I switched hasOne and belongsTo in your models.
Also.. third argument on hasOne of Application Model is not required since value from $primaryKey will be used since its defined, however you have to specify the third argument in belongsTo of User model
I have two table : users and profile.
A user may have one or multiple profile. I want to access the combined data of both table: 'ID' in user table is foreign key in profile table
User model :
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'first_name','last_name', 'email', 'password','phone','user_type',
];
protected $hidden = [
'password', 'remember_token',
];
public function profile()
{
return $this->hasMany(profile::class);
}
}
Profile model is :
class profile extends Model
{
protected $fillable = [
'id','relationship_status','dob','height',
'weight','primary_language'
];
protected $primaryKey = 'profile_id';
public function User()
{
return $this->belongsTo(User::class,'id','id');
}
}
Change your user model profile relationship like this
User Model
public function profile()
{
return $this->hasOne(Profile::class); //assuming your user has single profile
}
Profile model
class Profile extends Model
{
protected $fillable = [
'id', 'user_id', 'relationship_status','dob','height',
'weight','primary_language'
];
//add user_id field in profiles table
//protected $primaryKey = 'profile_id'; //no need of this, because you have id field in profiles table
public function user()
{
return $this->belongsTo(User::class);
}
}
after that you can fetch data like this
$user = User::find(2);
dd($user);
dd($user->profile)
When fetching multiple users details, then use eager loading
$users = User::with('profile')->get();
foreach($users as $user){
dd($user->profile)
}
Check details https://laravel.com/docs/5.6/eloquent-relationships#one-to-one
My tables :
users :
id fname email
brands:
id title user_id_made
each user has many brands and each brand belongTo an user.
class Brand extends Model
{
protected $table = 'brands';
protected $fillable = array('title_fa',
'title_en','logo','user_id_made');
public function user()
{
return $this->hasOne('App\Models\User');
}
}
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'fname' ,'lname' , 'username', 'email', 'password',
];
protected $hidden = [
'password', 'remember_token',
];
public function brand()
{
return $this->belongsTo('App\Models\Brand','user_id_made');
}
}
my code hasn't any output about users .
$data['brands'] = \DB::table('brands')->find(1);
var_dump($data['brands']);
return;
This will not load user. I will suggest you to use model instance in place of DB instance. if you want to load user with brands then you can use laravel's eager loading.
First in your Brand.php model
You need to pass the second argument as user_id_made to hasOne function otherwise it will assume it user_id.
public function user()
{
return $this->hasOne('App\Models\User','user_id_made');
}
You can do something like that.
$data['brands'] = Brand::with('user')->find(1);
Now If you will return $data['brands'] then it will return user information also.
Hope this will help.
In my model i added protected $table, but when i'm going to use it laravel does't use it. This is my role models:
class Role extends Model
{
protected $table = 'role';
protected $primaryKey = 'ROLE_ID';
protected $casts = [
'ACTIVE' => 'boolean',
];
protected $fillable = [
'ROLE', 'ACTIVE', 'TYPE'
];
public $timestamps = false;
public function groups()
{
return $this->belongsToMany(Group::class, GroupRole::class, 'ROLE_ID', 'GROUP_ID');
}
}
And this is Group model:
class Group extends Model
{
protected $table = 'groups';
protected $primaryKey = 'GROUP_ID';
protected $fillable = [
'GROUP_ID', 'GROUP_NAME', 'PARENT_GROUP', 'ACTIVE'
];
protected $casts = [
'ACTIVE' => 'boolean',
];
public $timestamps = false;
public function type()
{
return $this->belongsTo(GroupType::class, 'TYPE', 'TYPE_ID');
}
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class, 'GROUP_ID', 'ROLE_ID');
}
}
And this is group_role table model. It handles many to many relation between role and group:
class GroupRole extends Model
{
protected $table = 'group_role';
protected $primaryKey = 'GROUP_ROLE_ID';
protected $fillable = [
'COMMENT', 'ROLE_ID', 'GROUP_ID'
];
public $timestamps = false;
}
Problem begin when i want to use this models. For example:
$role = App\Role::first();
$groups = $role->groups;
Laravel returns this error messages:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'favian_mydb.App\GroupRole' doesn't exist (SQL: select groups.*, App\GroupRole.ROLE_ID as pivot_ROLE_ID, App\GroupRole.GROUP_ID as pivot_GROUP_ID from groups inner join App\GroupRole on groups.GROUP_ID = App\GroupRole.GROUP_ID where App\GroupRole.ROLE_ID = 1)
I tried to replace App\GroupRole with group_role and executing in mysql. It works fine. Am i missing something?
The Problem is in your roles relation:
public function roles()
{
return $this->belongsToMany(Role::class, GroupRole::class,'GROUP_ID','ROLE_ID');
}
The belongsToMany expects the intermediate table name as second argument, not the class name.
So you have to define it like this:
public function roles()
{
return $this->belongsToMany(Role::class, 'group_role','GROUP_ID','ROLE_ID');
}
I think the problem is in you relation functions. Try to use strings instead of Model::class.
Example:
return $this->return $this->belongsTo('App\GroupType', 'TYPE', 'TYPE_ID');
Hope this works.