0

メッセージ、グループ、ユーザー、メンバーシップの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 を使用してグループのメンバーであるかどうかを確認しようとしていますが、1 つのクエリが大量に生成されます。

 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 Load クエリは必要ありません。user_id は Membership に含まれているため、最後のクエリは役に立ちません。

アクセス可能なメソッドをに変更してみました

 def accessible
   self.groups.with_memberships.exists?(:user_id=>User.current.id)
 end

しかし、その後、Group Load クエリで user_id を使用しようとし、もちろん失敗します。最後のクエリを削除するにはどうすればよいですか? レール 2.3.2

4

2 に答える 2

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)
于 2009-10-05T12:53:38.573 に答える