Как вернуть записи, связанные со списком дочерних элементов вложенного набора? - PullRequest
0 голосов
/ 12 февраля 2011

Rails версия 3.0.3, я новичок в rails, но давно нахожусь в webdev.

Я использую вложенный набор.

У меня есть таблицы "posts", "tags" и "label_posts"

сообщений has_and_belongs_to_many ярлыки
ярлыки has_and_belongs_to_many сообщений

метки act_as_nested_set

У меня есть label_id, и я хочу получить все сообщения, связанные с этим ярлыком и его дочерними элементами, как один упорядоченный набор результатов.

Допустим, у меня есть ярлыки: «L1, L1.1, L1.1.1, L1.2, L2»

Учитывая L1 и зная, что у меня есть L1, L1.1, L1.1.1 и L1.2, я обычно запускаю запрос:

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

Этот запрос вернет все сообщения, связанные с каждым из этих ярлыков.

Итак, как это сделать с помощью рельсов?

<Ч />

EDIT:

Итак, вот мой контроллер

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

А вот и вывод сервера rails

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"

Я не уверен, что выбран метод выбора.

<Ч />

РЕДАКТИРОВАТЬ ОТВЕТ:

Итак, вот ответ, который я получил

@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)

Ответы [ 2 ]

2 голосов
/ 12 февраля 2011

1001 * попробовать *

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)

0 голосов
/ 12 февраля 2011

Давайте сначала соберем идентификаторы метки (label_id) и ее потомков.

Затем с помощью метода выбора массива Ruby выберите те сообщения, которые связаны с соответствующими метками.

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