我的模特是:
class Person < ActiveRecord::Base
has_one :archive, :dependent => :destroy
class Archive < ActiveRecord::Base
belongs_to :person
并非所有人都有档案,这意味着Person.find(xxx).archive
可能会返回nil
。
我需要为所有人返回部分属性集,包含或不包含档案。
当我做其中一件时:
Person.includes(:archive).select(:full_name)
Person.includes(:archive).select('persons.full_name')
正如预期的那样,我只得到所有人的full_name
。
请注意,我使用的是includes
而不是joins
,否则会从结果中排除没有归档的人。
然后我尝试添加一个archive
Person.includes(:archive).select('persons.full_name', 'archives.title')
但后来我收到了这个警告:
弃用警告:您似乎急于加载在字符串SQL代码段中引用的表(人员,档案之一)。例如:
Post.includes(:comments).where("comments.title = 'foo'")
目前,Active Record识别字符串中的表,并且知道将comments表连接到查询,而不是在单独的查询中加载注释。但是,在不编写完整的SQL解析器的情况下执行此操作本身就存在缺陷。由于我们不想编写SQL解析器,因此我们将删除此功能。从现在开始,当您从字符串引用表时,必须明确告诉Active Record:
Post.includes(:comments).where("comments.title = 'foo'").references(:comments)
如果您不依赖隐式联接引用,则可以通过设置
config.active_record.disable_implicit_join_references = true
来完全禁用该功能。 (从(irb)的irb_binding调用:125)
Sooooo ..我在声明的最后添加了references(:archive)
:
Person.includes(:archive).select('persons.full_name','archives.title').references(:archive)
但现在我获得了所有属性和 none 的归档。
我确信有一个干净简单的解决方案,但找不到它。有些帮忙吗?
答案 0 :(得分:2)
嗯,我想我找到了答案。
此代码适用于我:
Person.joins("LEFT JOIN archives ON persons.id = archives.person_id")
.select('persons.full_name', 'archives.title')
直到现在我发现它没有任何问题...
(我需要使用LEFT JOIN,因为不是所有人都有档案,我仍然需要检索所有人)
顺便说一下,我使用了这个非常有用的教程,以防你想要更好地理解:答案 1 :(得分:0)
title属性存在,只是inspect
的默认实现只显示基表中的列。你可以做到
Person.includes(:archive).select('persons.full_name','archives.title').
references(:archive).collect { |p| [p.full_name, p.title]}
让自己相信这一点。
如果您只需要这两个值,请考虑使用pluck
(尽管您需要在rails 4.1上使用pluck返回多个列)