【问题标题】:Ruby on Rails ActiveRecord include queries happen while not specifing itRuby on Rails ActiveRecord 在未指定时包含查询
【发布时间】:2012-10-05 20:48:10
【问题描述】:

每当我尝试调用它时:

  @ships = Ship.find(:all,
                    :conditions => {:sold => params[:sold]},
                    :order => "ship.id desc")

从这个模型:

class Ship < ActiveRecord::Base
    self.table_name = 'ship'

    self.inheritance_column = :ruby_type
    belongs_to :brand, :class_name => 'Brand', :foreign_key => :brand    
    belongs_to :fuel, :class_name => 'Fuel', :foreign_key => :fuel    
    has_many :ship_pictures, :class_name => 'ShipPicture'
    has_many :reservations, :class_name => 'Reservation'    
end

我最终得到了这些查询:

  Ship Load (0.0ms)  SELECT "ship".* FROM "ship" WHERE "ship"."sold" = 'false' ORDER BY ship.id desc
  Brand Load (0.0ms)  SELECT "brand".* FROM "brand" WHERE "brand"."name" = 'Percedes' LIMIT 1
  Fuel Load (0.0ms)  SELECT "fuel".* FROM "fuel" WHERE "fuel"."name" = 'Air' LIMIT 1
  ShipPicture Load (0.0ms)  SELECT "ship_picture".* FROM "ship_picture" WHERE "ship_picture"."ship_id" = 2
  Brand Load (1.0ms)  SELECT "brand".* FROM "brand" WHERE "brand"."name" = 'Volksship' LIMIT 1
  Fuel Load (1.0ms)  SELECT "fuel".* FROM "fuel" WHERE "fuel"."name" = 'Nuclear Reactor' LIMIT 1
  ShipPicture Load (0.0ms)  SELECT "ship_picture".* FROM "ship_picture" WHERE "ship_picture"."ship_id" = 1

为什么会这样?我没有打电话 :include 或类似的东西?我想加入 ship_pictures 并且只获得该加入的第一个结果。

第二件事:什么被认为更好:符号方式还是方法方式?

【问题讨论】:

  • 不确定您所说的“符号或方法方式”是什么意思。你是在说Ship.find(:all, :conditions =&gt; {...}, :include =&gt; ...)Ship.where(...).include(...) 的区别吗?
  • 另外,你可能有理由想要这样做,但你不需要为可以推断类的关联指定:class_name,例如has_many :ship_pictures 会自动使用ShipPicture
  • 是的,我在 Ship.find(:all, :conditions =&gt; {...}, :include =&gt; ...)Ship.where(...).include(...) 之间进行了修改
  • 好的,谢谢tristanm。我使用了反向脚本,因为我已经有了数据库结构,但我现在已经删除了它。
  • 要回答您关于哪个更好的问题,绝对要使用新的可链接方法而不是旧式 find(:all, :conditions...) API。我认为从 Rails 3.1 开始,旧 API 已被弃用。

标签: ruby-on-rails activerecord join include


【解决方案1】:

这里似乎不是延迟加载。如果使用延迟加载,我预计只会看到三个查询 BrandFuelShipPicture,使用 SQL 如下:

WHERE "ship_picture"."ship_id" IN [1,2]

Ship 模型中是否还有其他代码调用了这些关联?

如果上面的查找器来自控制器,您可能会在视图中的某个位置调用ship.fuelship.brandship.ship_pictures。这是 N+1 查询的常见原因。如果不是来自控制器,则很可能是在查询结果上运行的其他代码。

【讨论】:

  • 我不敢相信我这么瞎 >:(。我在调用 render :json => @ships.to_json(:include => :ship_pictures) 叹息。谢谢你的快速和好的遮阳篷!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多