Как я могу разрешить пользователю обновлять только те отзывы, которые он написал с помощью канкана?

Я следил за рельсовой трансляцией Райана Бейтса об использовании канкана, но не понимаю, почему проверка того, написал ли пользователь обзор, а затем разрешение ему редактировать его, если он это сделал, не работает для меня.

вот код у меня есть:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.role == "admin"
      can :manage, :all
    else
      can :read, :all
      if user.role == "author"
        can :create, Review
        can :update, Review do |review|
          review.try(:user) == user
        end
      end
    end
  end
end

Я хочу, чтобы авторы могли обновлять только написанные ими обзоры, все остальные возможности работают нормально, но в ту минуту, когда автор может обновлять отзывы, написанные всеми, что я здесь упускаю?

Я использую возможность решить, отображать ли ссылку на редактирование в частичном отзыве:

  <% if can? :update, Review %>
    testing
  <% end %>

Спасибо за любую помощь!


person Dave    schedule 08.06.2011    source источник


Ответы (3)


На ваш взгляд, вы должны написать что-то вроде

<% if can? :update, @review %>
  testing
<% end %>

Поэтому передайте фактический объект обзора, а не только класс.

person nathanvda    schedule 08.06.2011
comment
спасибо за ответ, он все еще не работает с использованием @review, но с использованием «review» работает. - person Dave; 08.06.2011

Пытаться:

review.user_id == user.id

Вместо:

review.try(:user) == user

Вы сравниваете два разных экземпляра одного и того же пользователя. Это, вероятно, использует user.object_id для сравнения. Rails 3.1 исправляет это, используя Identity Map для ActiveRecord.

Подтвердить:

user.find(1) == user.find(1)
person Erik Peterson    schedule 08.06.2011

Я бы не стал использовать блок для этого варианта использования и вместо этого использовал подход хеширования атрибутов CanCan:

if user.role == "author"
  can :create, Review
  can :update, Review, :user_id => user.id
end

Это будет сравниваться на основе идентификатора пользователя, а не самого объекта пользователя.

person Paul Russell    schedule 08.06.2011