Dlaczego akcje „zorientowane na zakres” (szczególnie akcje „indeksowe”) są traktowane inaczej w Pundit?

Piszę w odniesieniu dohttps://github.com/elabs/pundit#scopes

Jestem pod wrażeniem, żeupoważnienie powinien odpowiedzieć na pytanieCzy masz dostęp do tego zasobu?, tj. atrue/false odpowiedź. Dotyczy to wszystkich akcji z wyjątkiemindex, co według doktorów Pundita powinno powrócić inaczejActiveRecord::Relationzależy od tego, kto pyta. Na przykład anAdministrator dostajescope.all, podczaszwykły użytkownik dostajescope.where(:published => true).

app / policy / post_policy.rb

class Scope < Struct.new(:user, :scope)
  def resolve
    if user.admin?
      scope.all
    else
      scope.where(:published => true)
    end
  end
end

app / controllers / posts_controller.rb

def index
  @posts = policy_scope(Post)
end

Moja rezerwacja jest taka, że ​​jest to śliskie zbocze i wkrótce dodam prezentację do zakresów (np.scope.all.order('created_at ASC')) - i po prostu czuję się dziwnie robiąc topolityka autoryzacji.

Oczywiście, mogę przenieść to do kontrolera ...

def index
    @post = policy_scope(post)
    if user.admin?
        @post = @post.order( 'created_at ASC' )
    end
end

... ale czy to jest zadanie kontrolera? I nie sądzę, by słusznie było dodać takie wezwanie do widoku. Więc może to powinna być metoda modelowa?

Co powiesz na plusy / minusy robienia następujących rzeczy?

app / controllers / posts_controller.rb

To utrzymujeindex tak jak inne metody, z jednym wywołaniemauthorizei jedno wywołanie metody modelowej.

def index
  authorize(Post)
  @posts = Post.index(current_user)
end

app / policy / post_policy.rb

To po prostu daje prawdziwą / fałszywą odpowiedź. Czy masz autoryzację? Tak lub nie.

def index?
    user.admin? || user.regular_user?
end

app / models / post.rb

A w modelu możemy uzyskać tak fantazyjne, jak nam się podoba.

def self.index(user)
  if user.admin?
    Post.all.order('created_at ASC')
  else
    Post.where(user_id: user.id)
  end
end

Myśli?

questionAnswers(1)

yourAnswerToTheQuestion