Rails 4如何包含多态

时间:2015-10-30 20:02:20

标签: ruby-on-rails activerecord eager-loading

我的Webcam模型有很多Urls

class Webcam < ActiveRecord::Base

  has_many :urls, -> {  where('kind LIKE ?','preview_url')}, :as => :urlable, :dependent => :destroy

  has_one :preview_url, -> { where('kind LIKE ?', 'preview_url') }, :as => :urlable, :dependent => :destroy, :class_name => 'Url'

end

class Url < ActiveRecord::Base

  belongs_to :urlable, polymorphic: true

end

所以Webcam.joins(:preview_url).where(:id=>cam_ids)确实有效,但我仍然为每个摄像头调用了一个SQL。

  Url Load (0.2ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9756], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
  CACHE (0.0ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9756], ["urlable_type", "Webcam"], ["kind", :preview_url]]
  Url Load (0.2ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9759], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
  CACHE (0.0ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9759], ["urlable_type", "Webcam"], ["kind", :preview_url]]
  Url Load (0.2ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9760], ["urlable_type", "Webcam"], ["kind", "preview_url"]]
  CACHE (0.0ms)  SELECT  "urls".* FROM "urls" WHERE "urls"."urlable_id" = $1 AND "urls"."urlable_type" = $2 AND (kind LIKE 'preview_url') AND "urls"."kind" = $3  ORDER BY "urls"."id" ASC LIMIT 1  [["urlable_id", 9760], ["urlable_type", "Webcam"], ["kind", :preview_url]]

如何避免这些sql调用?

1 个答案:

答案 0 :(得分:0)

You should use .includes(:urls, :preview_url) (not .joins) to avoid N+1 queries problem (see Rails Guides on the topic).

You should also have a separate urls.kind value for preview_url because you can't distinguish it from other urls now.