Rails AR:编写需要多个连接的范围的最有效方法

时间:2012-10-11 09:13:29

标签: mysql ruby-on-rails performance

考虑以下

class Room < ActiveRecord::Base
  belongs_to :user
  has_many :authorisations, dependent: :destroy
  has_many :authorised_users, through: :authorisations, source: :user

  scope :without_privacy_restriction, where(public: true)
end

class User < ActiveRecord::Base
  has_many :rooms, dependent: :destroy
  has_many :accessible_rooms, through: :authorisations, source: :room
  has_many :authorisations
end

用户可以是房间的所有者,也可以是其他用户房间的授权用户。最重要的是,用户可以被定义为管理员(users表中的另一列代表这一点),无论如何都可以访问所有房间。

我希望能够编写一个有效的范围,将给所有可访问的房间返回给给定的用户,但我无法确定实现此目的的最有效方法。

1 个答案:

答案 0 :(得分:0)

这实际上不是范围。

我会做两件事

class Room < ActiveRecord::Base

  class << self

    def accessible_by(user) # classmethods and scopes are interchangeable
      if user.admin?
        scoped # this returns "all" but not as an array, so you can chain
               # starting with rails4 you can use "all".
      else
        user.accessible_rooms
      end
    end

  end

end

这是在用户是否为admin时返回不同的范围。然后,为了获得相同范围的所有者,您可以通过为拥有的房间添加授权来对“所有权”进行非规范化

class Room < ActiveRecord::Base

  after_create :authorise_owner

  def authorise_owner
    authorisations.create(user_id: owner_id)
  end

end

所以你不需要做奇怪的连接。