Rails ActiveRecord 协会

发布于 2024-10-20 07:39:18 字数 679 浏览 7 评论 0原文

好的,这是我的问题。我有 3 个不同的模型:人员、角色、客户和商店。客户有很多商店,也可以有很多人。商店里人很多。人们有各种各样的角色。 1 人可以在多个商店工作,并且他们在每个商店可能具有不同的角色。

例如。乔可能是一家商店的助理经理和另一家商店的经理。我希望能够做的是通过做类似的事情来扮演正确的角色

Store.find(1).people.find(1).roles
(would return 'assistant manager' for example) or

Store.find(2).people.find(1).roles
(would return 'manager' for example). Is this possible to do in ActiveRecord?

我创建了一个表 :roles_people ,它具有以下定义:

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

但是我无法弄清楚如何使用该表使关联正常工作。有人能指出我正确的方向吗?

谢谢

Okay, so here is my question. I have a 3 different models, People, Roles, Client, and Store. Clients have many Stores and can also have many people. Stores have many people. People have various roles. 1 Person can work at multiple stores, and they may have different roles at each store.

For example. Joe may be an assistant manager at one store and a manager at another store. What I would like to be able to do is pull the correct roles by doing something like

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

(would return 'assistant manager' for example) or

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

(would return 'manager' for example). Is this possible to do in ActiveRecord?

I've created a table :roles_people which has the following definition:

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

However i can't figure out how to get associations to work properly using this table. Can anyone point me in the right direction?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

雪化雨蝶 2024-10-27 07:39:18
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 对象,那么这没什么大不了的。

希望这个答案足够了:)

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

Assume that all of those classes inherit from ActiveRecord::Base ;)

You're going to need to setup the migration and database structure to mirror these relationships. For each belongs_to there is an :object_id field on the table reference the appropriate table's id.

Your query is going to need to look something like:

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

I would probably add a method to the store model to make this a little easier:

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

This way you can find the roles using:

Store.find(1).roles_for(1)

Or, better yet:

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

Which changes our finder to:

Store.roles_for(1, 1)

I would say that this last method is the most ideal since it causes only a single query, while each of the other options execute two queries to the database per role look-up (one to find the store, and one to get the roles for a person_id). Of course if you already have the Store object instantiated then it's not a big deal.

Hopefully this answer was sufficient :)

放飞的风筝 2024-10-27 07:39:18

我认为您想要的是 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

I think what you want is 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

You'll also need to add relationships to RolePerson:

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

Is that what you were looking for?

Very helpful link @blog.hasmanythrough.com

未央 2024-10-27 07:39:18

has_and_belongs_to_many 是你的朋友。

class Person < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

这样,您就可以通过调用 Person.roles.all 来获取此人拥有的所有角色。生成的查询将使用 people_roles 表。您还可以使用 has_many :through 但必须自己为连接表构建模型类并自己维护所有关联。有时是必要的,有时则不是。取决于您实际模型的复杂程度。

has_and_belongs_to_many is your friend.

class Person < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

That way, you can get all roles the person has by calling Person.roles.all. The resulting query is going to use the people_roles table. You can also use has_many :through but have to build model classes for the join table yourself and maintain all the associations yourself. Sometimes it's necessary, sometimes it's not. Depends on the complexity of your actual model.

你的心境我的脸 2024-10-27 07:39:18

好问题。你无法完全做到你想要的,但我想我们可以接近。
为了完整起见,我将回顾一下您的数据结构:

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

您会看到该角色不需要到客户端的链接,因为可以直接从商店找到它(我假设存储仅由一个客户端“拥有”)。

现在,角色既链接到又链接到商店,因此一个人可以在每个商店拥有不同的角色。
为了以干净的方式找到这些,我将使用辅助函数:

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),我们不再有任何关于商店的概念(我们是如何到达那里的)。

希望这有帮助。

Nice question. You can't do exactly what you wanted, but i guess we can come close.
For completeness, i am going to recap your datastructure:

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

You see that the role does not need the link to the client, because that can be found straightaway from the store (i am assuming a stored is "owned" by only one client).

Now a role is linked both to a person and a store, so a person can have different roles per store.
And to find these in a clean way, i would use a helper function:

class Person
  has_many :roles
  has_many :stores

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

So you can't write something like

store.people.first.roles

to get the roles of the first person working for that store.
But writing something like:

store.people.first.roles_for(store)

is not too hard i hope.

The reason why this is so is because in the context of the person (-> store.people.first) we no longer have any notion of the store (how we got there).

Hope this helps.

格子衫的從容 2024-10-27 07:39:18

您需要更改 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

You need to change your table name in people_roles and you can drop both store and client references:

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

Role is something that belongs only to people.

You then need to use 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

Than you can query:

Store.find(1).people.find(1).roles
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文