我有4个模型,消息,组,用户,会员
class Group < ActiveRecord::Base
has_many :memberships
has_many :users, :through => :memberships
has_many :groups_messages
has_many :messages, :through => :groups_messages, :order => "created_at desc"
named_scope :with_memberships, :include => :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :group
end
class User < ActiveRecord::Base
has_many :memberships
has_many :groups, :through => :memberships
end
class Message < ActiveRecord::Base
has_and_belongs_to_many :recipients, :class_name => "User"
has_many :groups_messages
has_many :groups, :through => :groups_messages
def accessible
self.groups.with_memberships.map(&:user_ids).include?(User.current.id)
end
end
消息可以发布到组,如果当前用户是该组的成员,他有权阅读它。
我正在尝试检查用户是否是具有Message.accessible的组的成员,但它产生了一个查询:
Group Load (0.1ms) SELECT `groups`.* FROM `groups` INNER JOIN `groups_messages` ON `groups`.id = `groups_messages`.group_id WHERE ((`groups_messages`.message_id = 381)) AND ((`groups_messages`.message_id = 381))
Membership Load (0.1ms) SELECT `memberships`.* FROM `memberships` WHERE (`memberships`.group_id = 1)
User Load (0.1ms) SELECT `users`.id FROM `users` INNER JOIN `memberships` ON `users`.id = `memberships`.user_id WHERE ((`memberships`.group_id = 1))
我不需要用户加载查询 - user_id包含在Membership中,因此最后一个查询是无用的。
我尝试将可访问的方法更改为
def accessible
self.groups.with_memberships.exists?(:user_id=>User.current.id)
end
然后它尝试在Group Load查询中使用user_id,当然也失败了。 我怎么能摆脱最后的查询? Rails 2.3.2
答案 0 :(得分:0)
我认为对用户的查询是由对User.current.id
的调用引起的。你能尝试将参数传递给可访问的方法吗?
def accessible_to( user )
self.groups.with_memberships.map(&:user_ids).include?(user.id)
end
我想这将从一个控制器中调用,其中current_user是(按照惯例)设置的,所以在某些控制器操作中你会做类似的事情:
@message.accessible_to(current_user)
答案 1 :(得分:0)
在更好地理解了rails后,我意识到它发生了,因为 map(&amp;:user_ids)
def accessible
self.groups.with_memberships.map(&:user_ids).include?(User.current.id)
end
这种行为绝对正常,我的错误是我希望它的行为类似于 groups.membership_user_ids ,并且表现为 groups.user_ids
通过更改为
来修复def accessible
Membership.exists?(["user_id=? and group_id in (?)",User.current.id,self.group_ids])
end
实际上包含的部分(User.current.id)由于某种原因甚至无法正常工作。