开发者

How do I return records associated to a list of children of a nested set?

Rails version 3.0.3, I am new to rails, but been in webdev for a long time.

I am using awesome nested set.

I have the tables "posts", "labels", and "labels_posts"

posts has_and_belongs_to_many labels

labels has_and_belongs_to_many posts

labels acts_as_nested_set

I have a label_id and I want to get all posts that are associated to that label and its children, all as a single ordered result set.

Let us say that I have Labels: "L1, L1.1, L1.1.1, L1.2, L2"

Given L1, and knowing that therefore I h开发者_StackOverflowave L1, L1.1, L1.1.1, and L1.2, I would normally run the query:

select id, title
from posts
where exists (select * from labels_posts where labels_posts.post_id = posts.id and labels_posts.label_id IN ('L1', 'L1.1', 'L1.1.1', 'L1.2'))
order by created_at desc

This query would return all the posts associated with each of those labels.

So, what is the rails way to do this?


EDIT:

So, here is my controller

@label = Label.find(params[:label])
@posts = Post.all.select do |post|
  post.label_ids.include?(@label.self_and_descendants.map(&:id))
end

And here is the rails server output

Label Load (0.5ms)  SELECT "labels".* FROM "labels" WHERE ("labels"."cached_slug" = 'caribbean') LIMIT 1
Post Load (0.6ms)  SELECT "posts".* FROM "posts"
Label Load (0.2ms)  SELECT "labels".id FROM "labels" INNER JOIN "labels_posts" ON "labels".id = "labels_posts".label_id WHERE ("labels_posts".post_id = 1 )
Label Load (0.8ms)  SELECT "labels".* FROM "labels" WHERE ("labels"."lft" >= 1 AND "labels"."rgt" <= 8) ORDER BY "lft"
Label Load (0.1ms)  SELECT "labels".id FROM "labels" INNER JOIN "labels_posts" ON "labels".id = "labels_posts".label_id WHERE ("labels_posts".post_id = 2 )
CACHE (0.0ms)  SELECT "labels".* FROM "labels" WHERE ("labels"."lft" >= 1 AND "labels"."rgt" <= 8) ORDER BY "lft"

I am not sure the select method is the one that is needed.


EDIT ANSWER:

So here is the answer I arrived at

@label = Label.find(params[:label])
@posts = Post.order('posts.created_at desc').where('labels_posts.label_id IN (?)', @label.self_and_descendants.map(&:id)).includes(:labels)


try

Post.all(:conditions => "id = labels_posts.post_id AND label_posts.label_id in('L1', 'L1.1', 'L1.1.1', 'L1.2')", :include => [:label => labels_posts], :order => :created_at)


Lets first collect the ids of the Label (label_id) and its children.

Then use the Ruby Array Select method to select those posts which are associated with the appropriate labels.

label_ids = Label.find(label_id).children.map(&:id).push(label_id)
posts = Post.all.select{|post| post.label_ids.include?(label_ids)}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜