Rails запрос существования многих ко многим - PullRequest
4 голосов
/ 30 марта 2012

Вид запроса на активную запись ruby-noob:

Magazine
  has_many :subscriptions

User
  has_many :subscriptions

Subscription
  belongs_to :user
  belongs_to :magazine

В контроллере я хотел бы эффективно спросить, подписывается ли current_user на a_magazine. Я думаю, что это должно быть что-то вроде следующего ...

Subscription.where("user_id = ? and magazine_id = ?", current_user.id, a_magazine.id).count > 0

а) выглядит правильно? б) есть ли более эффективный способ (предполагая индексы на ФК) в) стилистически, есть ли более приемлемый или лаконичный способ?

Заранее спасибо ...

Ответы [ 3 ]

3 голосов
/ 30 марта 2012

Более краткий способ сделать это включает использование метода хеширования объявления запросов, который легче читать и оставляет меньше возможностей для ошибок:

Subscription.where(:user_id => current_user.id, :magazine_id => a_magazine.id).any?

Вы также можете добавить :through отношения для проверки на основепользователь или журнал соответственно.

class User < ActiveRecord::Base
  has_many :subscriptions
  has_many :magazines, :through => :subscriptions
end

Это делает тестирование на совпадения действительно простым:

user = User.find(1)
user.magazines.where(:magazine_id => magazine_id).any?
3 голосов
/ 30 марта 2012

Похоже на классическое has_many: благодаря ассоциации со мной. Смотрите здесь:

http://guides.rubyonrails.org/association_basics.html#the-has_many-through-association

По сути, у вашего пользователя есть журналы has_many через подписку, а у ваших журналов также много пользователей через подписку. После настройки этих ассоциаций ваш код должен упроститься.

2 голосов
/ 30 марта 2012

Вы должны изменить свою ассоциацию на отношения has_many :through. Таким образом, у вас есть модель, которая ссылается на обе модели.

class Magazine < ActiveRecord::Base
  has_many :users, :through => :subscriptions
end

class User < ActiveRecord::Base
  has_many :magazines, :through => :subscriptions
end

class Subscription < ActiveRecord::Base
  belongs_to :user
  belongs_to :magazine
end

Теперь вы можете проверить, кому Subscriptions a User принадлежит вот так ...

User.find(current_user.id).subscriptions # => Returns a list of Magazine id's

И вы можете проверить, имеет ли User значение от Magazine до Subscription, например ...

User.find(current_user.id).subscriptions.find_by_magazine_id(1).any? 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...