2015-01-01 1 views
1

OK. То, что я пытаюсь достичь, основано на создании списка связанных статей на основе конкретной статьи, и я хочу получить эти связанные статьи на основе категорий, связанных с этой статьей. У меня есть простая взаимозависимость между этими двумя моделями: статья и категория (таблица соединений называется articles_categories). Я хочу создать запрос связанных статей на основе статей, которые имеют одинаковые category_id как одну статью. Например, статья # 1 связана с категорией # 1 и категорией # 2. Я хочу написать запрос, который захватывает идентификаторы категорий статьи # 1, затем запрашивает модель статьи для всех статей, связанных с теми же категориями, категориями # 1 и категорией # 2. Я пробовал все под солнцем и не могу понять этого. Я пробовал .join заявления различных видов и ничего не работает. Я пытался разбить его на две части ниже:Запрос ассоциации has_and_belongs_to_many в Ruby

я могу захватить все категории идентификаторов конкретной статьи, которые я хочу сослаться так:

article_cat_ids = @article.category_ids 

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

Итак, мой вопрос: как мне получить массив статей, связанных с идентификаторами категорий в массиве article_cat_ids. И в качестве бонусного кикера, я хотел бы исключить конкретную статью, которую я первоначально ссылался на создание article_cat_ids, чтобы список статей не включал статью, в которую я пытаюсь получить связанные статьи.

Любая помощь будет оценена по достоинству.

ответ

0

Звучит интересно. Я думаю, что ваша модель данных великолепна.

Давайте попробуем сделать это в SQL в первую очередь. Это приведет нас к решению ActiveRecord.

select a1.id 
from articles a1 
inner join articles_categories ac1 on ac1.article_id = a1.id 
inner join articles_categories ac2 on ac2.category_id = ac1.category_id 
inner join articles a2 on a2.id = ac2.article_id 
where a2.id = $1 
    and a1.id <> $1; 

Это работает, но вы также можете использовать подзапрос IN-clause. Вы должны провести сравнительный анализ, чтобы узнать, что лучше работает с вашими данными.

Теперь, как мы переводим это в ActiveRecord? Честно говоря, вы, возможно, не захотите. В любом случае вы будете писать много SQL.

article_id = 1 # or whatever 
Article. 
    joins('articles_categories ac1 on ac1.article_id = articles.id'). 
    joins('articles_categories ac2 on ac2.category_id = ac1.category_id'). 
    joins('articles a2 on a2.id = ac2.article_id'). 
    where(['a2.id = ? and a1.id <> ?', article_id]) 

AR - это нечеткая абстракция в этих ситуациях. Это должно работать, но, на мой взгляд, оно менее читаемо, чем простой SQL.

Обратите внимание, что это решение является единственным запросом. Остерегайтесь других решений, которые связаны с несколькими запросами. Здесь легко справиться с проблемой запроса 1 + N, если вы используете, например. петля в рубине.