HABTM или имеет много сквозной модели в Rails 3 - PullRequest
0 голосов
/ 11 марта 2011

Я разрабатываю модель сертификации для следующих целей.У пользователя будет набор сертификатов, скажем, [A, B, C, D].У статьи также будет набор сертификатов, скажем, [B, D].Я хочу, чтобы я мог найти статьи, где их сертификаты представляют собой некоторое подмножество (читай: любое подмножество) сертификатов пользователя.То есть, если бы статья имела сертификаты [A, B, E], она не была бы возвращена, но если бы у нее были [A] или [A, D] или что-то еще, она вернулась бы в порядке.На самом деле, я предполагаю, что это пересечение user.certs с art.certs и обеспечение того, что результирующий набор равен art.certs.size.Я реализовал это как HABTM, так как мне действительно не нужен доступ к объекту соединения, но у меня возникают проблемы при разработке логики.Я закончил тем, что сделал что-то вроде этого:

@certs = @user.certifications.collect{|c| c.id}
Article.all(:joins=>:certifications, 
         :group=>Article.attributes_for_sql, 
         :select=>'articles.*', 
         :conditions => ['certifications.id in (?)', @certs], 
         :having=> "count(articles.id)=(select (count(article_id)) from articles_certifications where article_id = articles.id group by article_id)")

Кажется, это работает, но чрезвычайно уродливо.

В любом случае, как мне разработать эти отношения, чтобы сделать это как можно проще икак бы выглядел пример решения?

Спасибо за любую помощь, я действительно бился головой об стену на этом.

Ответы [ 2 ]

0 голосов
/ 19 марта 2011

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

SELECT *
FROM articles a
WHERE NOT EXISTS
    (SELECT NULL
    FROM articles_certificates ac
    WHERE ac.article_id = a.id AND ac.certificate_id NOT IN
        (SELECT cu.certificate_id
        FROM certificates_users cu INNER JOIN users u ON cu.user_id = u.id
        WHERE u.id = #{user_id})
    )

Я не эксперт в запросе ActiveRelations, поэтому мой запрос очень напоминает мой SQL :), извините

Article.joins(:certificates).
    all(:conditions => "NOT EXISTS (SELECT NULL FROM articles_certificates WHERE articles_certificates.certificate_id NOT IN ? AND articles.id = articles_certificates.article_id)", #{user.certificates})
0 голосов
/ 11 марта 2011

ОК, немного прояснив ситуацию, вот моя официальная попытка ответа: D

Насколько я понимаю, вы хотите статьи со всеми сертификатами, которые есть у пользователя.Сертификаты одинаковы для всех моделей, поэтому идентификаторы должны работать нормально.

Почему бы не попробовать простой оператор IN, такой как:

@user_certs = @user.certifications.all(:select => "id")
Article.all(:conditions => ["certification_id IN ?", @user_certs])

Это должно откатить любую статью с таким жесертификация в качестве пользователя, на которого вы смотрите.

Я надеюсь, что у вас возник вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...