CanCanCan gem: обработка случая, когда нет вошедшего в систему пользователя
Я использую камень CanCanCan (v.12.0) для базовой авторизации. мой User
Модель не использует понятие ролей. Все, что я пытаюсь сделать, это убедиться, что пользователь вошел в систему, прежде чем он сможет что-то сделать с моей основной моделью, Topic
,
Я считаю, что я написал свой Ability
класс правильно. мой TopicsController
имеет index
метод, который неудивительно, что отображает все темы пользователя.
Проблема в том, что первый if
в index.html.erb
успешно, когда нет зарегистрированного пользователя - это не имеет смысла для меня. Я что-то упускаю из виду?
# ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # default user
# as long as a user is logged in and owns the topic it can do anything it likes with it
can [:manage], Topic do |topic|
!user.new_record? && topic.try(:user) == user
end
end
-
# topics_controller.rb
class TopicsController < ApplicationController
load_and_authorize_resource # CanCanCan gem
def index
end
...
end
-
# index.html.erb
<% if can? :read, Topic %>
<% @topics.each do |topic| %>
<%# Display all the topics %>
<% else %>
<%# Handle the case where the user can't read Topics %>
<% end %>
1 ответ
Вам необходимо авторизовать пользователя для конкретного экземпляра:
<%= if can? :read, topic %>
Когда вы пытаетесь авторизовать пользователя для всего класса, как вы делали выше, CanCanCan игнорирует любые условия, определенные в Ability, потому что он не может определить user
отношение для всего Topic
модель; это может сделать только для одного topic
пример. К сожалению, в AFAIK нет способа авторизации для отношения, поэтому вам придется авторизоваться для каждого экземпляра в отношении.
Как вариант, в версии 1.4load_and_authorize_resource
в контроллере должна инициализироваться @topics
на основе current_user
только если Способность определена без блоков. Тем не менее, это почти тривиально, чтобы сделать это "вручную":
@topics = current_user.topics