在视图中访问ActiveRelation

时间:2013-07-15 03:18:16

标签: ruby ruby-on-rails-3.2 rails-activerecord

我有两个模型,在people表中创建了相应的外键:

class Person < ActiveRecord::Base
    belongs_to :family

class Family < ActiveRecord::Base
    has_many :people

如果我执行以下操作,我会得到一个对象 - @ family_members - 作为实例变量,我没有问题:

@family_members = Family.find(1)

我可以在我的视图中轻松访问'子'人员表字段:

@family_members.people.first_name

但是,如果我使用arel方式与“where”等我得到一个“ActiveRecord :: Relation”,而不是一个普通的对象,这让我难以理解如何从人们那里访问相同的“first_name”字段像我上面访问过的表:

@family_members = Family.where(:id => 1) 
or even
@family_members = Family.joins(:people).where(:id => 1)

(甚至需要“连接”?) 我知道使用“.first”会导致查询运行:

@family_members = Family.where(:id => 1).first

但它返回一个数组,而不是一个对象,所以如果我在我的视图中使用:

@family_members.people.first_name

我得到了“方法'人'未知'错误。

如何访问people表的'first_name'字段,就像我使用“find”创建的对象但使用ActiveRecord关系一样?

*已添加信息7/15 * ** * ** * *

澄清我在寻找什么 - 如果我在编写SQL而不是Arel,那么我会写这些:

SELECT f.home_phone, f.address, p.first_name, p.last_name, p.birthday 
FROM families f INNER JOIN people p ON p.family.id = f.id WHERE family_id = 1

将该查询的结果加载到结果集中,我可以访问:

myResultSet("home_phone") -- the home_phone from the families table
myResultSet("address") -- the address from the families table
myResultSet("first_name") -- the first_name from the people table
myResultSet("birthdate") -- the birthdate from the people table

如果查询中的两个表具有同名字段,我只需使用“AS”以其他名称请求其中一个字段。 我在网络应用程序中使用了这种查询/结果集多年,我试图推断出如何在Rails和ActiveRecord中做同样的事情。

1 个答案:

答案 0 :(得分:0)

@family_members.people.first_name不应该工作所以我很惊讶你发现它有效... @family_members包含一个Family对象,@ family_members.people是一个Person对象数组。

你称之为@family_members的事实似乎让我觉得你期待它是一个人的数组......在这种情况下,正确的代码将是......

@family_members = Family.find(1).people # finds people in first Family object

如果您希望@family_members只包含第一个家庭成员,那么......

@family_members = Family.find(1).people.first

如果你想要一系列所有家庭成员的名字,那么......

@family_members = Family.find(1).people # finds people in 1st Family object
@family_members.map {|member| member.first_name} # array of first_name

@family_members = Family.find(1)@family_members = Family.where(:id => 1)在功能上是相同的。在每种情况下,检索数据库中的第一个Family对象可能包含零个,一个或多个人。

为了清楚起见,上面所有示例中的“1”都是指检索哪个Family对象,而不是系列中的哪个Person。