开发者

Eager loading Rails 3 ActiveRecord Model with conditions on the base table

开发者 https://www.devze.com 2023-03-01 16:19 出处:网络
I\'m trying to get this result: All Posts that are published AND have a specific tag, and include the tags (to avoid n+1)

I'm trying to get this result: All Posts that are published AND have a specific tag, and include the tags (to avoid n+1)

Here is my code:

@posts = Post.includes(
  :tags
).where(
  :status => 'published', :tags => { :name => params[:tag_name] }
).order(
  'published_at DESC'
)

Here is the rails s output:

Parameters: {"tag_name"=>"family"} Post Load (1.1ms) SELECT "posts"."id" AS t0_r0, "posts"."title" AS t0_r1, "posts"."body" AS t0_r2, "posts"."published_at" AS t0_开发者_开发知识库r3, "posts"."excerpt" AS t0_r4, "posts"."slug" AS t0_r5, "posts"."created_at" AS t0_r6, "posts"."updated_at" AS t0_r7, "posts"."status" AS t0_r8, "tags"."id" AS t1_r0, "tags"."name" AS t1_r1, "tags"."created_at" AS t1_r2, "tags"."updated_at" AS t1_r3 FROM "posts" LEFT OUTER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" LEFT OUTER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id" WHERE "posts"."status" = 'published' AND "tags"."name" = 'family' ORDER BY published_at DESC Completed in 102ms

Here is the error message:

/home/sam/.rvm/gems/ruby-1.8.7-p334@global/gems/activerecord-3.0.6/lib/active_record/attribute_methods.rb:44:in `eval': missing attribute: status

I can see from the SQL that the posts.status column is aliased to t0_r8, but how can I get it to properly respect my condition?

EDIT query that I had, that does work:

@posts = Post.joins(
  :tags
).where(
  "posts.status = ? AND tags.name = ?",
    "published",
    params[:tag_name]
).order(
  "published_at DESC"
)


Hmmm maybe I just didn't completely understand the way that ActiveRecord works; this is the solution I came up with:

@posts = Post.includes(
  :tags
).joins(
  :tags
).where(
  "posts.status = ? AND tags.name LIKE ?",
  "published",
  params[:tag_name]
).order(
  "published_at DESC"
).paginate(
  :per_page => 5,
  :page => params[:page],
  :order => "published_at DESC"
)

My mistake was in assuming that joins and includes would duplicate functionality, apparently not:

Post Load (1.7ms) SELECT "posts".* FROM "posts" INNER JOIN "posts_tags" ON "posts_tags"."post_id" = "posts"."id" INNER JOIN "tags" ON "tags"."id" = "posts_tags"."tag_id" WHERE (posts.status = 'published' AND tags.name LIKE 'family') ORDER BY published_at DESC Tag Load (1.1ms) SELECT "tags".*, t0.post_id as the_parent_record_id FROM "tags" INNER JOIN "posts_tags" t0 ON "tags".id = t0.tag_id WHERE (t0.post_id IN (7,6,4))

0

精彩评论

暂无评论...
验证码 换一张
取 消