我有两个模型:生产者和事件。 联接模型(EventRole)链接两个模型并存储“角色”属性:
create_table :event_roles do |t|
t.integer :role
t.references :producer, foreign_key: true
t.references :event, foreign_key: true
end
我想知道如何列出事件X的所有生产者,但返回事件中生产者的“角色”。
那有可能吗?
我成功列出了事件的所有生产者,但是(不出所料)它没有返回“角色”:
Producer.joins(:event_roles).where(event_roles: { event_id: 1 })
达到这样的结果的最优雅的方法是什么?
=> [
{id: 1, name: "Producer 1", role: "manager"},
{id: 5, name: "Producer 5", role: "admin"}
]
答案 0 :(得分:2)
进行联接时,它不会像数据库中的联接那样返回表,但是信息在那里。可以通过以下方式获取该信息:
data = Producer.includes(:event_roles).where(event_roles: { event_id: 1 }).pluck(:id, :name, :role)
更新:您当然可以将我的原始答案链接到:
data = Producer.includes(:event_roles).where(event_roles: { event_id: 1 }).pluck(:id, :name, :role).map {|i| {id: i[0], name: i[1], role: [2]} }
附录: 如果我想要一个包含两个表中数据的哈希数据结构,我有时会做一件事:
data = EventRole.includes(:producer).where(event_roles: { event_id: 1 }).group_by {|r| r.producer }
这将返回哈希而不是数组,其中每对都是一个对象,因此格式为{=> event_role对象,等等。}然后,您可以遍历散列并从所需的每一列中提取任何列。当您有两个要访问多个列的表时,这更适用...
data.each do |producer, event_role|
puts "the producer is #{producer.name} and role is #{event_role.role}"
end
=> 'the producer is Producer 1 and role is manager'
'the producer is Producer 5 and role is admin'
应该返回以下内容:
=> [
[1, "Producer 1", "manager"],
[5, "Producer 5", "admin"]
]
然后您可以将数据处理为适合您的表单。
data.map! {|i| {id: i[0], name: i[1], role: [2]} }
=> [
{id: 1, name: "Producer 1", role: "manager"},
{id: 5, name: "Producer 5", role: "admin"}
]
这里需要注意的一个问题:如果您有includes
或joins
且具有相同名称的列,则需要指定所需的列:
data = Producer.includes(:event_roles).pluck('producers.id','event_roles.id')