如何结合分页和授权的优势

时间:2014-02-20 14:00:33

标签: ruby-on-rails performance pagination cancan will-paginate

我有一个群组页面,其中显示了所有成员的列表。 GroupsController#show 的代码看起来像这样

  def show
    if @group
      @members = @group.members.order(:last_name, :first_name)
      @members = @members.page(params[:page]).per_page(25) # pagination
    end
    respond_with @group
  end

我们在我们的应用程序中使用CanCan授权,我想将显示的成员限制为那些用户实际可以:read

这样的工作:

      @members = @group.members.order(:last_name, :first_name).select{|member| can? :read, member}
      @members = @members.paginate(params[:page], per_page: 25)

但据我所知,它会破坏分页的性能优势,即首先从数据库中加载所有成员,然后选择可见的成员。 像

一样交换它
      @members = @group.members.order(:last_name, :first_name)
      @members = @members.page(params[:page]).per_page(25).select{|member| can? :read, member}

也不会这样做,因为视图需要一个特定的WillPaginate :: Collection,其中包含页面数,当前页面等元信息 - 而不是一个简单的数组。

有没有一种正确的方法可以像在关系和分页之间链接Proc一样? 我的google fu让我失望。

完整的代码可以在github

上看到

1 个答案:

答案 0 :(得分:1)

您可以先使用accessible_by将结果限制为当前用户可以查看的结果:

@members = @group.members.accessible_by(current_ability).order(:last_name, :first_name
@members = @members.page(params[:page]).per_page(25) # pagination

有关详细信息,请参阅https://github.com/ryanb/cancan/wiki/Fetching-Records