Мне очень нравится ответ Адама Таннера, но я бы поставил его немного по-другому. Во-первых, способ, которым Организация ассоциируется с админами, не работает, как описано - вам придется иметь другой внешний ключ в вашей пользовательской таблице и указать это в ассоциации has_one :admin
. Но я не думаю, что это хороший путь, так как он ограничивает вас одним администратором для каждой организации и ограничивает пользователя, принадлежащего к одной организации.
Моя версия немного сложнее, но я думаю, что она хорошо работает. Во-первых, администратор должен быть той роль, которую пользователь имеет или не имеет с организацией. Сначала я обращусь к проблеме пользователя/организации и сохранил проблему с адресом позже.
Вот миграциях, которые вы можете улучшить с любыми другими полями они нуждаются:
create_table :organizations do |t|
# your fields go here
end
create_table :users do |t|
# your fields go here
end
create_table :memberships do |t|
t.integer :user_id
t.integer :organization_id
t.boolean :is_admin
end
add_index :memberships, [:user_id, :organization_id]
Как вы можете видеть, мы добавим таблицу ЧЛЕНСТВО, которая собирается для подключения пользователей и организаций. Мы также добавляем индекс, чтобы немного ускорить ассоциацию. Теперь для моделей:
class Organization < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
end
class User < ActiveRecord::Base
has_many :memberships
has_many :organizations, :through => :memberships
def membership_in organization
self.memberships.detect{|m| m.organization = organization}
end
def is_admin_for? organization
self.membership_in(organization).is_admin?
end
def set_admin_for organization, value
self.membership_in(organization).update_attribute(:is_admin, value)
end
end
class Membership < ActiveRecord::Base
belongs_to :organization
belongs_to :user
end
Здесь мы подключаем наших пользователей и организации через членство. Пользователь может быть администратором для любой из организаций, к которым они принадлежат. Я создал несколько методов для установки и получения статуса администратора в организации в пользовательской модели.
Следующий адрес: Я уже решал один в своем блоге мой:
http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/
Если у вас есть какие-либо вопросы, пожалуйста, спрашивайте. Удачи!
UPDATE
Эдвард М. Смит отметил в комментариях, что мои методы администратора не очень отказоустойчивой.Я пытался сохранить код как можно более чистым для примера, но у него есть точка. Так вот beefier версия, которая объясняет пытается использовать членство в организации, пользователь не часть:
def is_admin_for? organization
membership = self.membership_in(organization)
return false if membership.nil?
membership.is_admin?
end
def set_admin_for organization, value
membership = self.membership_in(organization)
return false if membership.nil?
membership.update_attribute(:is_admin, value)
end
Как всегда, тест-разработки на основе лучше, но я обычно не имеют время, чтобы сделать это для вопросов stackoverflow :)
Вопрос с рельсов/рубин noob. 'membership_in' возвращает либо нуль, либо экземпляр организации, верно? Что происходит на is_admin_for? позвонить, где пользователь не находится в организации? Разве это не вызов is_admin? на ноль и, следовательно, ошибка? –
Очень верно, это много кода, который я напечатал для ответа stackoverflow, поэтому я не создал много отказов или использовал TDD, как если бы я работал для рабочего кода :) Хороший улов, и я исправлю Это. –
О, я не критиковал. Я все еще работаю над пониманием Ruby (нужно было, например, искать метод «обнаружить» в коллекциях), поэтому я хотел знать, правильно ли я понял. :) –