Я сталкиваюсь с различным поведением в среде разработки и тестирования, используя devise и cancan.
Я использую:
- rails 3.2.2
- cancan1.6.7
- devise 2.0.4
- капибара 1.1.2
У меня есть контроллер:
class ProductsController < ApplicationController
before_filter :authenticate_user!, :only => [:edit]
authorize_resource
...show, edit...
С
class ApplicationController < ActionController::Base
protect_from_forgery
check_authorization :unless => :devise_controller?
Мой тест:
- перейти на домашнюю страницу
- открыть список продуктов
- открыть 1 продукт
- изменитьэтот продукт
Перевод с использованием капибары:
scenario "test" do
visit("/");
click_link("Products")
click_link("Awesome Product 00001")
puts current_url
click_link("Edit")
puts current_url
save_and_open_page
end
Когда я делаю это в режиме разработки в своем браузере, я в конечном итоге на странице входа, как ожидается, и консоль печатает:
http://www.example.com/products/1
http://www.example.com/users/sign_in
Но при запуске моей спецификации я получил 403 с:
http://www.example.com/products/1
http://www.example.com/products/1/edit
Если я использую prepend_before_filter
вместо before_filter
, он работает ... Так что, похоже,это проблема с порядком фильтров.Мне удалось напечатать это:
403 ===>
[:verify_authenticity_token, "_callback_after_83(self)", "_callback_before_231(self)", "_callback_before_299(self)", :authenticate_user!, "_callback_after_309(self)", :set_locale, :set_mailer_options, :store_location]
prepend_before_filter ===>
[:verify_authenticity_token, :authenticate_user!, "_callback_after_83(self)", "_callback_before_231(self)", "_callback_before_299(self)", "_callback_after_309(self)", :set_locale, :set_mailer_options, :store_location]
in browser ===>
[:verify_authenticity_token, "_callback_before_5", "_callback_after_245(self)", :set_locale, :set_mailer_options, :store_location, :authenticate_user!, "_callback_before_305(self)"]
Я искал в Интернете порядок фильтров, но не смог найти ничего, касающегося devise и cancan (и очень мало о порядке фильтров в целом).Я не удовлетворен предложенным решением, так как там может быть более серьезная проблема ... Есть кто-нибудь подсказка об этом поведении?
спасибо
РЕДАКТИРОВАТЬ
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new
# The ability rules further down in a file will override a previous one.
# See https://github.com/ryanb/cancan/wiki/Ability-Precedence
default_abilities
if user.role_member?
member_abilities
end
if user.role_client?
client_abilities
end
if user.role_administrator?
administrator_abilities
end
end
# ------------------------------------
private
# define abilities for everyone, including guests
def default_abilities
can :index, :home
can :read, Product
can [:read, :subcategories], ProductCategory
end
# define abilities for administrators
def administrator_abilities
end
# define abilities for clients
def client_abilities
can :edit, Product
end
# define abilities for members
def member_abilities
can :read, Member
end
end