【问题标题】:Rails 4 - Restrict retrieved columns from associated modelsRails 4 - 限制从关联模型中检索到的列
【发布时间】:2014-06-21 08:38:24
【问题描述】:

我是 Rails 新手,在编写 Active Record 查询时,我注意到 all 列的 all 正在检索关联的表。我想告诉 Active Record 应该从哪些表中检索哪些字段。该怎么做呢?

我的模型及其关联如下:

class User < ActiveRecord::Base
  has_one :profile
  has_many :comments
  has_many :posts
end

class Profile < ActiveRecord::Base
  belongs_to :user
end

class Comment < ActiveRecord::Base
  belongs_to :user
  belongs_to :post
end

class Post < ActiveRecord::Base
  belongs_to :user
  has_many :comments
end

我正在关注 Rails Edge Guides,当我尝试使用 select("users.id, profiles.first_name, profiles.last_name, comments.comment") 指定字段列表时,我在 Rails 控制台上收到弃用警告(并且运行的 SQL 查询是 LEFT OUTER JOIN涉及的所有表中,但仍包括 所有 列):

DEPRECATION WARNING: It looks like you are eager loading table(s) (one of: users, posts) that are referenced in a string SQL snippet. For example: 

Post.includes(:comments).where("comments.title = 'foo'")

Currently, Active Record recognizes the table in the string, and knows to JOIN the comments table to the query, rather than loading comments in a separate query. However, doing this without writing a full-blown SQL parser is inherently flawed. Since we don't want to write an SQL parser, we are removing this functionality. From now on, you must explicitly tell Active Record when you are referencing a table from a string:

Post.includes(:comments).where("comments.title = 'foo'").references(:comments)

If you don't rely on implicit join references you can disable the feature entirely by setting `config.active_record.disable_implicit_join_references = true`. (called from irb_binding at (irb):34)

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    检查以下是否适合您

    Class User < ActivcRecord::Base
       default_scope select("column1, column2, column3")
    
    end
    

    【讨论】:

    • 我已经查看了default_scope,但问题是它将all 查询的指定列限制为模型。如果我想为不同的查询设置不同的列集怎么办?常规的scope 会起作用吗?
    • 您可以通过以下方式完成 Post.select(:field1, :field2).find(id)
    • 感谢您的回复。是的,这适用于 Post 模型,我没有收到任何弃用警告。现在,我将如何限制关联模型上的字段?说,我想做User.select(:field1, :field2).includes(:posts)之类的事情,我将如何限制从Post模型中检索到的字段?
    • 您关于 default_scope 的回答让我在 Edge Guides 中四处张望,我发现答案隐藏在指南本身的深处。感谢您为我指明正确的方向!
    【解决方案2】:

    深埋在 Rails Edge Guides 的 Active Record 查询接口中,我找到了答案。诀窍是使用特定关联类型的范围来限制检索到的字段。

    直接引自指南:

    4.1.3 belongs_to 的范围

    有时您可能希望自定义 belongs_to 使用的查询。这种定制可以通过范围块来实现。例如:

    class Order < ActiveRecord::Base
      belongs_to :customer, -> { where active: true },
                        dependent: :destroy
    end
    

    您可以在范围块内使用任何标准查询方法。

    因此,将select 方法添加到上述范围,并使用您要检索的字段列表就可以了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多