#ruby-on-rails #cancan
#ruby-on-rails #cancan
Вопрос:
Я просматривал railscast Райана Бейтса об использовании cancan, но я в замешательстве относительно того, почему проверка того, написал ли пользователь отзыв, а затем разрешение им редактировать его, если они есть, у меня не работает.
вот код, который у меня есть:
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 %>
Спасибо за любую помощь!
Ответ №1:
На ваш взгляд, вам следует написать что-то вроде
<% if can? :update, @review %>
testing
<% end %>
Поэтому передайте фактический объект обзора, а не просто класс.
Комментарии:
1. спасибо за ответ, это все еще не сработало с использованием ‘@review’, но использование ‘review’ работает.
Ответ №2:
Попробуйте:
review.user_id == user.id
Вместо:
review.try(:user) == user
Вы сравниваете два разных экземпляра одного и того же пользователя. Вероятно, для сравнения используется user.object_id. Rails 3.1 исправляет это, используя карту идентификации для ActiveRecord.
Для подтверждения:
user.find(1) == user.find(1)
Ответ №3:
Я бы не стал использовать блок для этого варианта использования и вместо этого использовал подход CanCan с использованием хеширования атрибутов:
if user.role == "author"
can :create, Review
can :update, Review, :user_id => user.id
end
Это будет сравниваться на основе идентификатора пользователя, а не самого пользовательского объекта.