D
D
Denis Kainazarov2014-12-15 14:22:06
Polymorphism
Denis Kainazarov, 2014-12-15 14:22:06

Laravel morph - what am I doing wrong?

Now I am writing code for a system of users, roles and privileges. A privilege can refer to both a user and a role. You can get the privilege of the user, but the privilege of the role is not obtained either directly or through the user. There is a suspicion that I am doing something wrong, but what?
db schema

Schema::create('users',function($table){
  $table->increments('id');
  $table->string('email');
  $table->string('password');
  $table->enum('status',['new','active','banned']);
  $table->boolean('is_remote')->default(false);
  $table->rememberToken();
  $table->timestamps();
  $table->softDeletes();
  $table->index(['id','email','status']);
});
Schema::create('roles',function($table){
  $table->increments('id');
  $table->string('name');
  $table->longText('description')->nullable();
  $table->timestamps();
  $table->softDeletes();
  $table->index(['id','name']);
});
Schema::create('users_roles',function($table){
  $table->increments('id');
  $table->integer('user_id')->unsigned();
  $table->integer('role_id')->unsigned();
  $table->timestamps();
  $table->softDeletes();
  $table->foreign('user_id')->references('id')->on('users');
  $table->foreign('role_id')->references('id')->on('roles');
});
Schema::create('permissions',function($table){
  $table->increments('id');
  $table->string('owner_type');
  $table->integer('owner_id')->unsigned();
  $table->string('name');
  $table->enum('status',['allowed','denied'])->default('allowed');
  $table->longText('description')->nullable();
  $table->timestamps();
  $table->softDeletes();
  $table->index(['id','owner_type','owner_id','name']);
});

User Model
class User extends Eloquent implements UserInterface, RemindableInterface {

  use UserTrait, RemindableTrait;

  /**
   * The database table used by the model.
   *
   * @var string
   */
  protected $table = 'users';

  protected $softDelete = true;

  /**
   * The attributes excluded from the model's JSON form.
   *
   * @var array
   */
  protected $hidden = array('password', 'remember_token');

  public function roles()
  {
    return $this->hasMany('UserRole');
  }

  public function permissions()
  {
    return $this->morphMany('Permission', 'owner');
  }
  
  public function watches()
  {
    return $this->morphMany('Watch', 'owner');
  }
}

Role model
class Role extends Eloquent {

  protected $softDelete = true;
  protected $fillable = ['name','description'];

  public function roles()
  {
    return $this->hasMany('UserRole');
  }

  public function permissions()
  {
    return $this->morphMany('Permission', 'owner');
  }
}

Model linking role and user
class UserRole extends Eloquent {

  protected $table='users_roles';
  protected $softDelete = true;
  protected $fillable = ['id_user','id_role'];


  public function user()
  {
    return $this->belongsTo('User');
  }

  public function role()
  {
    return $this->belongsTo('Role');
  }

}

Privilege Model
class Permission extends Eloquent {

  protected $softDelete = true;

  public function owner()
  {
    return $this->morphTo();
  }

}

Test Case
$user = new User();
  $user->email = 'test';
  $user->password = Hash::make('test');
  $user->status = 'new';
  $user->save();

  $role = new Role();
  $role->name='testMaster';
  $role->description='a dude who make ui tests';
  $role->save();

  $user_role = new UserRole();
  $user_role->user()->associate($user);
  $user_role->role()->associate($role);
  $user_role->save();

  $permission = new Permission();
  $permission->name='read site';
  $permission->owner()->associate($user_role);
  $permission->save();

  $permission = new Permission();
  $permission->name='test site';
  $permission->owner()->associate($user);
  $permission->save();

  $user = User::find(1);
  echo $user->roles()->first()->role->name; ## testMaster
  echo $user->permissions()->first()->name; ## test site
        echo $user->roles()->first()->role->permissions()->first()->name; ## А вот шиш с маслом!

on premissions->first() - Cannot access property on non-object
If anyone has any idea why - please let me know
Since I'm experimenting with eloquent at the moment - reasoned messages that I have hands from the sirloin or that the architecture is built wrong - only welcome)))

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Y
Yuri Tarakhonich, 2014-12-21
@iit

premissions->first() - Cannot access property on non-object

Try this:
Calling relays with parentheses returns a request builder object, but without parentheses, it immediately makes a request and returns the result.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question