2015-02-10 64 views
1

我想顯示登錄表單,而不是cancan訪問被拒絕的Flash消息。這是我的控制器Rails:在CanCan訪問被拒絕之前詢問用戶身份驗證

#app/controllers/oferts_controller.rb 
class OfertsController < ApplicationController 
    before_action :set_ofert, only: [:show, :edit, :update, :destroy] 
    load_and_authorize_resource :only => [:new, :edit, :destroy] 
    before_filter :authenticate_user!, :except => [:show, :index] 
    # GET /oferts 
    # GET /oferts.json 
    def index 
    @oferts = Ofert.areactive 
    end 

    # GET /oferts/1 
    # GET /oferts/1.json 
    def show 
    end 

    # GET /oferts/new 
    def new 
    @ofert = current_user.oferts.new 
    @ofert.purchasing_group = PurchasingGroup.new 
    end 

    # GET /oferts/1/edit 
    def edit 
    end 

    # POST /oferts 
    # POST /oferts.json 
    def create 
    .... 
    end 

    # PATCH/PUT /oferts/1 
    # PATCH/PUT /oferts/1.json 
    def update 
    .... 
    end 

    # DELETE /oferts/1 
    # DELETE /oferts/1.json 
    def destroy 
    ... 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_ofert 
     @ofert = Ofert.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def ofert_params 

     params.require(:ofert).permit(:title, :short_title, :description, :price, :normal_price, :ends_at, :ends_at_date, :ends_at_time) 
    end 
end 

出於某種原因,當我嘗試訪問需要登錄的操作,例如,「創造」,我只能從慘慘得到拒絕訪問的消息,但我不是重定向到登錄頁面因爲它應該,因爲我有:authenticate_user!控制器中的before_filter。

如何確定設備重定向登錄頁面的優先級,而不是cancan訪問被拒絕的flash消息?

感謝

更新: 這是我的Gemfile

source 'https://rubygems.org' 


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 
gem 'rails', '4.1.9' 
# Use mysql as the database for Active Record 
gem 'mysql2' 
# Use SCSS for stylesheets 
gem 'sass-rails', '~> 5.0.0' 
# Use Uglifier as compressor for JavaScript assets 
gem 'uglifier', '>= 1.3.0' 
# Use CoffeeScript for .js.coffee assets and views 
gem 'coffee-rails', '~> 4.0.0' 
# See https://github.com/sstephenson/execjs#readme for more supported runtimes 
# gem 'therubyracer', platforms: :ruby 

# Use jquery as the JavaScript library 
gem 'jquery-rails' 
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 
gem 'turbolinks' 
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 
gem 'jbuilder', '~> 2.0' 
# bundle exec rake doc:rails generates the API under doc/api. 
gem 'sdoc', '~> 0.4.0',   group: :doc 

gem 'money-rails', '~> 1.2.0' 

gem 'money', '~> 6.5.0' 
# Use ActiveModel has_secure_password 
gem 'bcrypt', '~> 3.1.7' 

gem 'foundation-rails' 
gem 'font-awesome-rails', '~>4.3.0.0' 
gem 'devise' 
gem "cancan" 
gem "rolify" 
gem "paperclip", "~> 4.2" 
gem 'rails-i18n', '~> 4.0.0' 
gem 'jquery-ui-rails' 
gem 'whenever', :require => false 
gem 'jquery-countdown-rails' 
# Use unicorn as the app server 
# gem 'unicorn' 

# Use Capistrano for deployment 
# gem 'capistrano-rails', group: :development 

# Use debugger 
# gem 'debugger', group: [:development, :test] 

group :development do 
    # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 
    gem 'spring' 
    gem 'quiet_assets', '~>1.1' 
end 

group :development, :test do 
    gem 'rspec-rails', '~> 3.0.0' 
    gem 'rspec-expectations' 
    gem 'factory_girl_rails', '~> 4.0' 
end 

group :test do 
    gem 'capybara', '~> 2.3.0' 
    gem 'capybara-email' 
    gem 'shoulda-matchers', '~> 2.7.0' 
    gem 'rspec-its' 
    gem 'rspec-activemodel-mocks', '~> 1.0.1' 
end 

回答

1

爲了記錄在案,這裏是傳統的和乾的方式來做到這一點。

class ApplicationController < ActionController::Base 

    # ... 

    rescue_from CanCan::AccessDenied, with: :access_denied 

    # ... 

    private 

    def access_denied(exception) 
    store_location_for :user, request.path 
    redirect_to user_signed_in? ? root_path : new_user_session_path, alert: exception.message 
    end 

end 

這將存儲請求的位置在會話中並呈現Devise登錄表單,如果用戶當前沒有包括在存儲位置的簽署將觸發器在成功登錄後重定向到請求的位置。

將代碼置於ApplicationController將在全局範圍內定義此類行爲。

如果你不需要每個控制器都需要這個,你可以自由地將rescue_from CanCan::AccessDenied, with: :access_denied行放在你想要的位置,OfertsController就在你的案例中。您還需要將access_denied方法列爲protected而不是private

+0

是的,你是對的我很久以前就這樣做了。傑傑奧 – SsouLlesS 2015-11-05 23:20:01

2

由於load_and_authorize_resource增加了一個before_action到控制器,我建議反演:

load_and_authorize_resource :only => [:new, :edit, :destroy] 
before_filter :authenticate_user!, :except => [:show, :index] 

,如:

before_filter :authenticate_user!, :except => [:show, :index] 
load_and_authorize_resource :only => [:new, :edit, :destroy] 

每次調用before_filterbefore_action時,它會將方法添加到隊列中,並在運行時按FIFO(先進先出)順序調用它們。

我也建議使用before_action代替before_filter因爲每Rails 4.2 Release Notes,因爲它已經從文檔中刪除,並會在將來的Rails的版本被淘汰,並最終被刪除* _filter的方法家人勸阻。

+0

嗯,我做了你的建議,現在我的控制器具有 的before_filter:的authenticate_user!:除了=> [:秀:指數] load_and_authorize_resource:只=> [:新:編輯:摧毀] 但它沒有改變它的行爲,仍然只顯示cancan的flash消息而不是重定向到登錄頁面...... =/ – SsouLlesS 2015-02-10 04:33:55

+0

你能告訴我你正在運行哪個版本的Rails,並且編輯你的原始文章並且包括Gemfile的內容?如果它不包含Devise和CanCan的版本,你能告訴我你正在運行哪個版本? – 2015-02-10 12:37:54

+0

我運行cancan和Devise的最後一個穩定版本,以及Rails 4,我在文章中添加了Gemfile。 – SsouLlesS 2015-02-10 17:31:55