2010-10-28 2 views
2

Я довольно новичок в настройке базы данных в Ruby и нуждаюсь в помощи в правильной настройке вместе с моделями. Может ли кто-нибудь помочь?Настройка базы данных и модели в Ruby On Rails

В основном у меня есть Организация, в которой будет как минимум 2 типа пользователей - Пользователь и Администратор. У организаций и пользователей есть адрес.

Я думал, что это было в основном три таблицы - Организация, Пользователь и Адрес, но затем действительно запутались, когда пытались думать о моделях и внешних ключах.

Может ли кто-нибудь предложить лучший способ организовать это?

Я запускаю Rails 3 с базой данных mySql.

Спасибо за ваше время

Sniffer

ответ

5

Мне очень нравится ответ Адама Таннера, но я бы поставил его немного по-другому. Во-первых, способ, которым Организация ассоциируется с админами, не работает, как описано - вам придется иметь другой внешний ключ в вашей пользовательской таблице и указать это в ассоциации 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 :)

+0

Вопрос с рельсов/рубин noob. 'membership_in' возвращает либо нуль, либо экземпляр организации, верно? Что происходит на is_admin_for? позвонить, где пользователь не находится в организации? Разве это не вызов is_admin? на ноль и, следовательно, ошибка? –

+0

Очень верно, это много кода, который я напечатал для ответа stackoverflow, поэтому я не создал много отказов или использовал TDD, как если бы я работал для рабочего кода :) Хороший улов, и я исправлю Это. –

+0

О, я не критиковал. Я все еще работаю над пониманием Ruby (нужно было, например, искать метод «обнаружить» в коллекциях), поэтому я хотел знать, правильно ли я понял. :) –

2
class Organization < ActiveRecord::Base 
    has_one :address, :as => :addressable 
    has_many :members, :class_name => "User" 
end 

class User < ActiveRecord::Base 
    has_one :address, :as => :addressable 
    belongs_to :organization 
end 

class Address < ActiveRecord::Base 
    belongs_to :addressable, :polymorphic => true 
end 

Я удалил админ ассоциацию, отчасти потому, что он не работает в любом случае, в основном потому, что, как Хайме сказал, что это неправильный способ пойти об этом (большинство разработчиков используют какую-то систему ролей). См. Сообщение Хайме о том, как создать расширяемую систему ролей.

Надеюсь, это поможет вам!

+0

Спасибо за ответ Adam. Посмотрев на некоторые ссылки: полиморфный атрибут имеет смысл. Я немного смущен тем, как я настроил свою базу данных (извините, что я новичок!). Правильно ли я думаю, что у Организации будут следующие поля id, orgname и User будут иметь поля id, username, organisation_id. Но я смущаюсь в таблице адресов, если у этого есть поля внешнего ключа для organisation_id и user_id? Означает ли это, что я добавляю поле внешнего ключа для каждого объекта, который запрашивает адрес? – Sniffer

+0

Или у вас есть две новые таблицы в ваших базах данных, называемые UserAddress (с адресами_ид и user_Id) и OrgAddresses (с адресами и org_id). Если да, то как вы устанавливаете их в модели? – Sniffer

+0

Вы верны для таблиц «Организация» и «Пользователь». Способ полиморфизма работает в Rails, так как таблица Address будет иметь столбец addressable_id и столбец addressable_type. Столбец addressable_id содержит идентификатор пользователя/организации/независимо от того, и addressable_type - это строка, которая содержит имя класса типа объекта, такого как «Пользователь»/«Организация»/«Независимо», чтобы он знал, какой класс создавать экземпляр, когда он вытаскивает его из базы данных. Вы можете создавать эти столбцы автоматически в своей миграции с помощью 't.references: addressable,: polymorphic => true'. –

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