Rails 4包含并选择

时间:2014-04-25 11:57:50

标签: ruby-on-rails ruby-on-rails-4

我的模特是:

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 的归档。

我确信有一个干净简单的解决方案,但找不到它。有些帮忙吗?

2 个答案:

答案 0 :(得分:2)

嗯,我想我找到了答案。

此代码适用于我:

Person.joins("LEFT JOIN archives ON persons.id = archives.person_id")
      .select('persons.full_name', 'archives.title')

直到现在我发现它没有任何问题...

(我需要使用LEFT JOIN,因为不是所有人都有档案,我仍然需要检索所有人)

顺便说一下,我使用了这个非常有用的教程,以防你想要更好地理解:
http://blog.arkency.com/2013/12/rails4-preloading/

答案 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返回多个列)