2011-02-25 48 views
15

用下面的代碼:如果請求是xhr,Rails中是否有方法可以跳過before_filter?

class TestsController < ApplicationController 
    skip_before_filter :load_something,  # how to skip these only 
        :load_something_else # if the request is xhr ? 

    def index 
    respond_to do |format| 
     format.html 
     format.js 
    end 
    end 

end 

有沒有辦法過濾器根據之前如果請求是不改變:load_something:load_something_else方法的JavaScript調用跳過?

謝謝!

回答

18

過去一直沒有乾淨的解決方案。假設你不能控制before_filters(或者不想改變它們),我會離開skip_before_filter並添加一個額外的before_filter,如果它是一個xhr方法,它只執行想要的方法。

因此,像

skip_before_filter :load_something,  # how to skip these only 
        :load_something_else # if the request is xhr ? 
before_filter :do_loads_if_xhr 

def do_loads_if_xhr 
    if request.xhr? 
    load_something 
    load_something_else 
    end 
end 

所描述的方法here只有工作,因爲條件是全球的應用程序:創建類當條件時才計算。不是每個請求。

[已更新] 但是,有一個更簡潔的方式來使skip_before_filter有條件。寫這樣的:

skip_before_filter :load_something, :load_something_else, :if => proc {|c| request.xhr?} 

同時還要注意skip_before_filter仍然完全支持,並且不會被棄用,因爲軌道4文檔似乎更喜歡的(相同的)skip_before_action。此外,文件完全不清楚這一點,必須在代碼中進行驗證。

3

你編碼過濾器?在這種情況下,你可以寫在他們裏面的if條款,而無需使用skip_before_filter

def load_something 
    unless request.xhr? 
    #Code 
    end 
end 

在另一方面,你可以讓自己的YOUT過濾器和委託:

before_filter :my_own_filter 

def my_own_filter 
    unless request.xhr? 
    load_something 
    load_something_else 
    end 
end 

我認爲這應該工作。

+0

不應該將這些方法放在一起,這樣如果前一個返回false,那麼其他的將不會運行,並且過濾器鏈將被暫停? – 2011-10-04 01:30:56

4

使用alias_method_chain來裝飾過濾器,所以如果請求是xhr,它們不會被執行。

def load_something_with_noxhr(*args) 
    load_something_without_noxhr(*args) unless request.xhr? 
end 

alias_method_chain :load_something, :noxhr 

(改變load_something成任何需要,_with__without_是文字,而後綴noxhr必須是你傳遞作爲alias_method_chain調用第二個參數是相同的。)

+0

看起來像'alias_method_chain'可能會被棄用/不推薦http://stackoverflow.com/questions/3689736/rails-3-alias-method-chain-still-used – colllin 2014-06-23 08:22:25

+1

不是不推薦,但現在(Ruby 2.1)有一個marvellos'prepend MyModule',它將你的模塊放在調用鏈的前面,所以模塊中的funcion實際上可以調用'super'並在「包含」類中調用同名的函數。 – rewritten 2014-07-07 01:19:59

37

嘗試這一行跳過濾波由一個條件:

skip_before_filter :load_something, :load_something_else, 
    :if => proc { request.xhr? } 

對於也可以使用的lambda(其具有在參數傳遞一個嚴格):

skip_before_filter :load_something, :load_something_else, 
    if: -> { request.xhr? } 

或參數:

skip_before_filter :load_something, :load_something_else, 
    if: ->(arg) { request.xhr? && arg } 
9

所有這些答案的需要,我認爲錯誤的做法。對條件使用skip_before_action是向後做的,並不像將條件添加到before_action本身那樣明確和清晰;所以這是我的建議:

before_action :require_password_change, unless: -> { request.xhr? } 

這樣,給別人讀你的代碼是什麼條件下,這種before_action運行下立即清晰或不運行,而不必依賴於他們在控制過這個skip_before_action發生的地方層次結構。

+0

這是我見過的最好的方法 – 2017-02-20 22:01:30

相關問題