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: