簡體   English   中英

Rails ActiveRecord協會

[英]Rails ActiveRecord Association

好的,這是我的問題。 我有3種不同的模型,人員,角色,客戶端和商店。 客戶有很多商店,也可以有很多人。 商店有很多人。 人們扮演着各種角色。 1個人可以在多個商店工作,並且每個商店可能扮演不同的角色。

例如。 喬可能是一家商店的助理經理,而另一家商店的經理。 我想做的是通過做類似的事情來扮演正確的角色

Store.find(1).people.find(1).roles
(例如,將返回“助理經理”)或

  Store.find(2).people.find(1).roles 
(例如,將返回“ manager”)。 在ActiveRecord中可以這樣做嗎?

我創建了一個表:roles_people,它具有以下定義:

\n create_table:roles_people,:id => false做| t |\n       t.references:角色\n       t.references:person\n       t.references:store\n       t.references:客戶\n 結束\n

但是我不知道如何使用此表使關聯正常工作。 誰能指出我正確的方向?

謝謝

class People
  belongs_to :client
  has_many :store_roles
end

class Roles
  has_many :store_roles
end

class StoreRole
  belongs_to :role
  belongs_to :people
  belongs_to :store
end

class Client
  has_many :stores
  has_many :people
end

class Store
  belongs_to :client
  has_many :store_roles
  has_many :roles, :through => :store_roles
end

假設所有這些類都繼承自ActiveRecord::Base ;)

您將需要設置遷移和數據庫結構以反映這些關系。 對於每個belongs_to ,表上都有一個:object_id字段,用於引用相應表的ID。

您的查詢將需要看起來像:

Store.find(1).roles.find(:all, :conditions => ["store_roles.person_id = ?", 1])

我可能會在商店模型中添加一種方法,以使其變得更容易一些:

def roles_for(person_id)
  roles.find(:all, :conditions => ["store_roles.person_id = ?", person_id])
end

這樣,您可以使用以下方式查找角色:

Store.find(1).roles_for(1)

或者,更好的是:

def self.roles_for(store_id, person_id)
  Role.find(:all, :joins => :store_roles, :conditions => ["store_roles.store_id = ? AND store_roles.person_id = ?", store_id, person_id])
end

這會將我們的查找器更改為:

Store.roles_for(1, 1)

我想說這最后一個方法是最理想的,因為它只引起一個查詢,而其他每個選項針對每個角色查找都對數據庫執行兩個查詢(一個用於查找存儲,一個用於獲取角色。一個person_id)。 當然,如果您已經實例化了Store對象,那么這沒什么大不了的。

希望這個答案就足夠了:)

我認為您想要的是has_many:through

class Person < ActiveRecord::Base
  has_many :roles_people
  has_many :roles, :through => :roles_people
end

class Store < ActiveRecord::Base
  has_many :roles_people
  has_many :people, :through => roles_people
end

您還需要向RolePerson添加關系:

class RolePerson < ActiveRecord::Base
  belongs_to :store
  belongs_to :person
  has_one :role
end

那是您要找的東西嗎?

非常有用的鏈接@ blog.hasmanythrough.com

has_and_belongs_to_many是您的朋友。

class Person < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

這樣,您可以通過調用Person.roles.all獲得該人的所有角色。 結果查詢將使用people_roles表。 您也可以使用has_many :through但必須自己為聯接表構建模型類,並自己維護所有關聯。 有時有必要,有時則沒有必要。 取決於實際模型的復雜性。

您需要在people_roles更改表名,並且可以刪除商店和客戶引用:

create_table :roles_people, :id => false do |t|
  t.references :role
  t.references :person
  t.references :store
end

角色是只屬於人的東西。

然后,您需要使用has_and_belongs_to_many:

class Person < ActiveRecord::Base
  has_many :roles
  has_many :stores, :through => :people_roles
end

class Store < ActiveRecord::Base
  has_many :roles
  has_many :people, :through => :people_roles
end

比您可以查詢:

Store.find(1).people.find(1).roles

好問題。 您不能完全按照自己的意願做,但我想我們可以接近。 為了完整性,我將重述一下您的數據結構:

class Client
  has_many :stores
end

class Store
  has_many :people
  has_many :roles
end

class Person
  has_many :roles
  has_many :stores
end

class Role
  belongs_to :store
  belongs_to :person
end

您會看到該角色不需要指向客戶端的鏈接,因為可以直接從商店中找到該鏈接(我假設一個存儲僅由一個客戶端“擁有”)。

現在,一個role既鏈接到一個person又鏈接到一個store ,因此一個人在每個商店中可以具有不同的角色。 為了以一種干凈的方式找到這些,我將使用一個輔助函數:

class Person
  has_many :roles
  has_many :stores

  def roles_for(store)
    roles.where("store_id=?", store.id)
  end
end

所以你不能寫這樣的東西

store.people.first.roles

獲得在該商店工作的第一個人的角色。 但是寫類似:

store.people.first.roles_for(store)

我希望不是太難。

之所以如此,是因為在人(-> store.people.first )的上下文中,我們不再具有商店的任何概念(我們如何到達那里)。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM