2010-10-28 103 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