Rails多对多存在查询

时间:2012-03-30 18:48:28

标签: sql ruby-on-rails ruby activerecord

一种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

a)看起来对吗? b)是否有更有效的方法(假设FK上的索引)c)风格上,是否有更接受或简洁的方式?

提前致谢...

3 个答案:

答案 0 :(得分:3)

看起来像经典的has_many:通过与我联系。见这里:

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

基本上,您的用户通过订阅了很多杂志,您的杂志也通过订阅拥有许多用户。设置这些关联后,您的代码应该简化。

答案 1 :(得分:3)

更简洁的方法是使用哈希方法来声明查询,这些查询更容易读取并且减少了出错的机会:

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?

答案 2 :(得分:2)

您应该将关联更改为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 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?