2014-01-22 3 views
0

Вопрос о Larvel's Eloquent ORM. Я уже смотрел на SO, извиняюсь, если упустил аналогичный вопрос.Напиши в hasMany отношения с Красноречивым ORM/Laravel

У меня есть модель User, и я пытаюсь написать массив разрешений обратно в модель UserPermissions через связь в модели User.

Я уже установил ссылку hasMany и могу получить правильные данные из объекта User ($user->roles), но не может решить, как писать, если это вообще возможно.

Это моя основная модель пользователя:

class User extends Eloquent { 

    protected $table = 'users'; 

    public $timestamps = false; 

    protected function roles() { 

     return $this->hasMany('UserPermission'); 

    } 

} 

и UserPermission модель:

class UserPermission extends Eloquent { 

    protected $table = 'users_permissions'; 

    public $timestamps = false; 

    protected $fillable = ['role_id', 'user_id']; 

} 

На данном этапе, я вернулся к спасению пользователя, а затем запустить UserPermission::insert(), что позволяет массив, который нужно передать, но я предпочел бы сделать это за один шаг, если это возможно.

Кто-нибудь знает, возможно ли это?

Спасибо!


UPDATE:

Структура таблицы ниже для вашего сведения:

пользователи таблицы

+------------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+------------------+------------------+------+-----+---------+----------------+ 
| id    | int(10) unsigned | NO | PRI | 0  | auto_increment | 
| username   | varchar(255)  | NO |  |   |    | 
+------------------+------------------+------+-----+---------+----------------+ 

users_roles стол

+------------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+------------------+------------------+------+-----+---------+----------------+ 
| id    | int(10) unsigned | NO | PRI | 0  | auto_increment | 
| name    | varchar(255)  | NO |  |   |    | 
| description  | varchar(255)  | YES |  | NULL |    | 
| url_access  | varchar(255)  | NO |  |   |    | 
+------------------+------------------+------+-----+---------+----------------+ 

users_permissions стол

+------------------+------------------+------+-----+---------+----------------+ 
| Field   | Type    | Null | Key | Default | Extra   | 
+------------------+------------------+------+-----+---------+----------------+ 
| id    | int(10) unsigned | NO | PRI | 0  | auto_increment | 
| role_id   | int(10) unsigned | NO |  |   |    | 
| user_id   | int(10) unsigned | NO |  |   |    | 
+------------------+------------------+------+-----+---------+----------------+ 

role_id относится к users_roles.id и user_id относится к users.id

В качестве справочной логики, users_roles таблица имеет url_access столбец, который содержит URL. Если пользователю назначена эта роль, у них есть доступ к подстраницам из этого URL-адреса.

+0

Не могли бы вы объяснить, что вы имеете в виду вас хотите «написать» на этом? – patrick

+0

Я могу получить массив разрешений, запросив '$ user-> role'. Я бы хотел, чтобы при создании пользователя или его обновлении можно было вернуть массив данных, например, '$ user-> role ([['role_id' => 1], ['role_id' => 2 ]]); '(user_id для таблицы ролей будет выведен из объекта User), затем вызовите' $ user-> save() 'и создайте обе строки в двух созданных таблицах. – aleayr

+0

Итак, если я правильно понимаю, вы хотите иметь возможность добавлять разные роли пользователю, если пользователь создан или обновлен, и вы хотите иметь строку в таблице для каждой роли, прикрепленной к пользователю? – patrick

ответ

3

Я не понимаю, почему вы используете hasMany отношения вместо belongsToMany. На самом деле кажется, что ваша структура базы данных уже такая, которая используется отношениями, принадлежащими toMany в Laravel.

Мое решение:

User.php

<?php 

class User extends Eloquent { 

    public function roles() { 
    return $this->belongsToMany('Role'); 
    } 

    protected $table = 'users'; 
    protected $guarded = array('id', 'password'); 
} 

Role.php

<?php 

class Role extends Eloquent { 

public function users() 
    { 
    return $this->belongsToMany('User'); 
    } 

protected $table = 'roles'; 
protected $guarded = array('id'); 

}

Соответствующие таблицы базы данных должны быть: users, roles и role_user. Они соответствуют соглашениям об именах Ларавеля, чтобы сделать простые вещи.

Теперь вы можете вызвать метод sync и передать массив к нему:

$user->roles()->sync(array(1, 2, 3)); 

синхронизации метод кратко описан в Eloquent ORM documentation.

+0

спасибо. функция «sync» - это чистое золото! –

1

Хорошо, вот что вы могли бы попробовать.

Определите отношение многих ко многим в как моделей.

class UserPermission extends Eloquent { 

protected $table = 'users_permissions'; 

public $timestamps = false; 

protected $fillable = ['role_id', 'user_id']; 

protected function users() { 

    return $this->belongsToMany('User'); 

    } 

} 

Затем, если вы создаете пользователь, используйте Laravel прикрепить метод для подключения пользователя к users_permission так:

$user = User::find(1); 

$user->roles()->attach(1); 

Прикрепление роли с идентификатором 1 пользователя с идентификатором of 1.

Так вы сможете либо прикрепить роль к пользователю, либо прикрепить пользователя к роли, если вы создаете пользователя или обновляете его.

Я действительно надеюсь, что это поможет вам. Если нет, не стесняйтесь спрашивать меня дальше. Несколько дней назад я определил многие-многие отношения с фотографиями и тегами, поэтому я вникаю в это, я бы сказал.

Кроме того, Laravel документы даже пример с пользователями и ролями:

http://laravel.com/docs/eloquent#many-to-many

+0

В вашем примере используется * hasMany * отношение, которое (согласно документации Laravel) имеет отношение «один ко многим». Вы не так много, как вы говорите. Кроме того, метод 'attach()' используется для присоединения одного объекта, а не массива объектов, который запрашивает автор этого вопроса. –

0

Из-за того, что вы читаете свой вопрос, он «звучит», и вы задаете тот же вопрос, с которым я столкнулся на днях.

Я надеюсь, что это поможет вам «массово обновлять» отношения при сохранении временных меток и избегать дублирования отношений.

Возможно, есть лучший способ. Я в этом уверен. Но это отлично сработало для того, чего я пытался добиться.

* Внимание: этот код не проверен. На самом деле точное решение, которое я использовал сам с некоторыми поиска/замены, чтобы помочь относиться к вашему вопросу

Class User extends BaseModel { 

    // [...] 


    public function roles() { 
     return $this->belongsToMany('Role'); 
    } 



    public function addUserRoles(Array $add_user_role_ids) { 
     /** 
     * Prevent Duplicate Relationships 
     */ 
     $existing_user_role_ids = $this->roles()->lists('user_role_id'); 

     $add_user_role_ids  = array_diff($add_user_role_ids, $existing_user_role_ids); 
     if ($add_user_role_ids == null) return false; 

     $add_user_role_ids  = UserRole::whereIn('id', $add_user_role_ids)->lists('id'); 
     if ($add_user_role_ids == null) return false; 

     /** 
     * Attach (Insert into Pivot Table) 
     */ 
     if (count($add_user_role_ids) > 0) { 
      $this->UserRoles()->attach($add_user_role_ids); 
      // Update timestamp 
      $this->touch(); 
     } 
     // Return successfully added user role ids Array 
     return $add_user_role_ids; 
    } 



    public function removeUserRoles(Array $user_role_ids) 
    { 
     $this->touch(); 
     $this->roles()->detach($user_role_ids); 
    } 

    // [...] 
} 

Eloquent Docs

Найди меня на Twitter: @ErikOnTheWeb

Смежные вопросы