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
Другие вопросы по тегам