2010-10-28 72 views
2

我对Ruby中的数据库设置非常陌生,需要帮助将它与模型一起正确设置。谁能帮忙?Ruby On Rails中的数据库和模型设置

基本上我有一个组织,它至少有两种类型的用户 - 会员和管理员用户。组织和用户都有一个地址。

我在想这基本上是三张表 - 组织,用户和地址,但是当尝试考虑模型和外键时会感到非常困惑。

任何人都可以提出最好的方式来组织这个?

我正在使用mySql数据库运行Rails 3。

感谢您的时间

嗅探器

回答

5

我很喜欢Adam Tanner的回答,但我会设置一点不同。首先,组织与管理员关联的方式并不像描述的那样工作 - 您必须在用户表中使用不同的外键,并在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

爱德华·史密斯在我的管理方法都不是很容错评论中指出。我试图尽量保持代码的清洁,但他有一个问题。因此,这里的是占试图组织使用会员比较强大版本的用户的一部分:

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

来自rails/ruby​​ noob的问题。 'membership_in'返回零或组织实例,对吧?在is_admin_for上会发生什么?调用用户不在组织中的位置?它不是调用is_admin吗?在零,因此一个错误? – 2010-10-28 21:38:35

+0

非常真实,这是我为了一个stackoverflow答案而输入的很多代码,所以我没有建立很多的容错性,或者像我想要的那样使用TDD代码:)好的,我会更正的它。 – 2010-10-28 21:57:40

+0

哦,我不是在批评。我只是还在努力理解Ruby(例如,必须查看集合上的'detect'方法),所以我想知道我是否正确理解了事情。 :) – 2010-10-28 23:51:46

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 

我已删除了管理员的关联,一方面是因为它没有反正工作,因为大多海梅说,这是错误的方式去了解它(大多数开发人员使用某种角色系统)。请参阅Jaime的文章,了解创建可扩展角色系统的好方法。

希望这可以帮助你!

+0

感谢您的答案亚当。看过一些引用:多态属性是有道理的。我只是有点困惑,我如何设置我的数据库(抱歉,我是一个新手!)。我是否正确地认为组织将具有以下字段id,orgname,并且用户将具有字段id,用户名,organisation_id。但是我对地址表感到困惑,如果这有外键字段为organisation_id和user_id?这是否意味着我为每个需要地址的对象添加一个外键字段? – Sniffer 2010-10-28 20:24:09

+0

或者你会在数据库中有两个名为UserAddress(带有address_Id和user_Id)和OrgAddresses(带有address_id和org_id)的新表。如果是的话,你如何在模型中对这些进行调整? – Sniffer 2010-10-28 20:50:48

+0

您对组织和用户表格是正确的。多态性在Rails中的工作方式是地址表将有一个addressable_id列和一个addressable_type列。 addressable_id列包含User/Organization/Whatever的ID,addressable_type是一个字符串,它保存诸如“User”/“Organization”/“Whatever”之类的对象类型的类名,以便它知道类在将它从数据库中拉出时实例化。您可以使用't.references:addressable,:polymorphic => true'在迁移过程中自动创建这些列。 – 2010-10-28 23:27:01