iit
@iit
TeamLead + php/js разработчик

Laravel morph — что я делаю не так?

Сейчас пишу код для системы пользователей, ролей и привилегий. Привилегия может относиться как к пользователю, так и к роли. Привилегию пользователя достать можно а вот привилегию роли ни напрямую ни через пользователя не получается. Есть подозрение что что-то я делаю не так, только вот что?

Схема бд
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']);
});

Модель пользователя
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');
	}
}

Модель роли
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');
	}
}

Модель связывающая роль и пользователя
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');
	}

}

Модель Привелегии
class Permission extends Eloquent {

	protected $softDelete = true;

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

}


Тестовый пример

$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; ## А вот шиш с маслом!

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

Если у кого есть идеи почему - сообщите пожалуйста

Так как в данный момент экспериментирую с eloquent - аргументируемые сообщения что у меня руки из филейной части или что архитектура выстроена не так - только приветствуются )))
  • Вопрос задан
  • 5012 просмотров
Решения вопроса 1
sofcase
@sofcase
Веб-разработчик
premissions->first() - Cannot access property on non-object

Попробуйте так:
...->premissions()->first();
Вызов релейшенов со скобками возвращает объект билдера запроса, а вот без скобок сразу делает запрос и отдаёт уже результат.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы