Я использую камень CanCan Райана Бэйта для определения способностей, и некоторые базовые функции не работают. У меня есть модель Product и контроллер Products, где мое действие индекса выглядит так:
def index
@req_host_w_port = request.host_with_port
@products = Product.accessible_by(current_ability, :index)
end
Я получаю сообщение об ошибке, когда пытаюсь получить продукты методом accessible_by
, я получаю эту ошибку:
Cannot determine SQL conditions or joins from block for :index Product(id: integer, secret: string, context_date: datetime, expiration_date: datetime, blurb: text, created_at: datetime, updated_at: datetime, owner_id: integer, product_type_id: integer, approved_at: datetime)
Мой класс способностей выглядит так:
can :index, Product do |product|
product && !!product.approved_at
end
Это выглядит как очень простой пример, поэтому я удивлен, что он терпит неудачу, и мне интересно, пропускаю ли я что-то простое (то есть слишком долго смотрю на мой код).
Я немного больше исследовал и провел простой тест. Если вы посмотрите на приведенный ниже код, один пример работает нормально, а другой не получается, когда они должны делать то же самое.
# This works
can :index, Product, :approved_at => nil
# This fails
can :index, Product do |product|
product && product.approved_at.nil?
end
Так что, похоже, проблема в том, как CanCan обрабатывает эти блоки. Я углубился в библиотеку и нашел, где возникла ошибка - в определении класса способностей CanCan:
def relevant_can_definitions_for_query(action, subject)
relevant_can_definitions(action, subject).each do |can_definition|
if can_definition.only_block?
raise Error, "Cannot determine SQL conditions or joins from block for #{action.inspect} #{subject.inspect}"
end
end
end
Итак, я проверил, что это за метод only_block?
. Метод возвращает true, если в определении can есть блок, но нет условий, которые не имеют смысла для меня, потому что весь смысл блока состоит в том, чтобы определить условия внутри блока, когда они слишком сложны для следующего синтаксиса:
can :manage, [Account], :account_manager_id => user.id
Любое понимание этого вопроса было бы замечательно! Я также подал вопрос на странице CanCan GitHub, но я дошел до того, что мне, возможно, придется отказаться от библиотеки. Тем не менее, я понимаю, что многие люди успешно используют CanCan, и это такая базовая функциональность, я думаю, что я должен делать что-то не так. Тем более, что репозиторий git был обновлен 3 дня назад, и Райан Бейтс упоминает о поддержке Rails 3 в README.
Спасибо!