Named Scopes and Created At

I am using named scopes in my Post model to find recently published posts:

named_scope :recently_published, :conditions => { :published => true }, :order => 'created_at DESC'

Posts HABTM tags, so I have my routes for those setup as:

map.resources :tags do |tag|   tag.resources :posts end

So that will give me a route to use, such as: tag_posts GET /tags/:tag_id/posts(.:format) {:action=>"index", :controller=>"posts"}

For the view, I find posts like this from the Posts controller: @tag = Tag.find(params[:tag_id]) @posts = @tag.posts.recently_published

Everything works as expected except the created_at attribute for my posts. When I print the created at timestamp in the view, it is actually printing the created timestamp for the tag.

<%= post.created_at.strftime('%B %d, %Y') %> gives me the created at timestamp for the tag, not the post.

Can someone help me fix this issue? Thank you!

By default when you access a habtm relationship like this rails does

select * from posts inner join post_tags on ... ...

So if the join table in the middle has an attribute with the same name as an attribute from joined table(s) they will collide. You can avoid this by adding :select => 'posts.*' to your habtm declaration

Fred

Sorry I have no time to test this, but try this:

named_scope :recently_published, :conditions => { :published => true }, :order => 'posts.created_at DESC'

I am pretty sure you can be specific about the table in this case.

CowboyonRails Chris Reister

Thanks for the replies. Unfortunately, neither of the solutions worked. I tried each on their own with no luck, and then I combined the two suggestions and still no luck. Here is what I have for the named scope in my Post model as of now:

named_scope :recently_published, :conditions => { :published => true }, :select => 'posts.*', :order => 'posts.created_at

Not sure if it helps, but here are the queries used to generate the page at: http://localhost:3000/tags/1/posts

Processing PostsController#index (for ::1 at 2010-01-03 11:13:21) [GET]   Parameters: {"tag_id"=>"1", "action"=>"index", "controller"=>"posts"}   Tag Load (0.2ms) SELECT * FROM "tags" WHERE ("tags"."id" = 1) Rendering template within layouts/application Rendering posts/index   SQL (0.2ms) SELECT count(*) AS count_all FROM "posts" INNER JOIN "posts_tags" ON "posts".id = "posts_tags".post_id WHERE ((("posts"."published" = 't') AND ("posts_tags".tag_id = 1 )) AND ("posts_tags".tag_id = 1 ))   Post Load (0.4ms) SELECT * FROM "posts" INNER JOIN "posts_tags" ON "posts".id = "posts_tags".post_id WHERE ("posts_tags".tag_id = 1 ) AND (("posts"."published" = 't') AND ("posts_tags".tag_id = 1 )) ORDER BY posts.created_at DESC   Category Load (0.2ms) SELECT * FROM "categories" WHERE ("categories"."id" = 2)   Tag Load (0.2ms) SELECT * FROM "tags" INNER JOIN "posts_tags" ON "tags".id = "posts_tags".tag_id WHERE ("posts_tags".post_id = 2 )   Category Load (0.2ms) SELECT * FROM "categories" WHERE ("categories"."id" = 1)   Tag Load (0.4ms) SELECT * FROM "tags" INNER JOIN "posts_tags" ON "tags".id = "posts_tags".tag_id WHERE ("posts_tags".post_id = 1 )   Category Load (0.5ms) SELECT * FROM "categories" ORDER BY name ASC LIMIT 5   SQL (0.1ms) SELECT count(*) AS count_all FROM "categories"   Post Load (0.3ms) SELECT posts.* FROM "posts" WHERE ("posts"."published" = 't') ORDER BY posts.created_at DESC LIMIT 5   Tag Load (0.3ms) SELECT * FROM "tags" ORDER BY name ASC LIMIT 5   SQL (0.1ms) SELECT count(*) AS count_all FROM "tags" Rendered layouts/_side_navigation (5.8ms) Completed in 86ms (View: 20, DB: 3) | 200 OK [http://localhost/tags/1/ posts]

Thanks again for the help and suggestions!

This is probably the query at fault - you want to put the :select option on the association itself, not the named scope

Fred

Thank you so much! That worked perfectly! :slight_smile: