2017-08-02 21 views
4

我已經閱讀了一些帖子,如Value whitelist using strong parameters in Rails 4,但它不是我所需要的。Rails 4參數;如何將一個參數白名單設置爲一組值

我有一個控制器,它需要一個ID並加載模型。它還可以選擇使用查詢字符串參數(style),該參數可以是3個值之一,即small,mediumlarge。這被傳遞給模型上的一個方法,使用它來獲取附加圖像(使用回形針)。我注意到,如果我傳遞一個無效的參數(例如style=wibble),那麼我會得到一個400錯誤,並通知內部文件路徑不存在。司閘員還指出這是一個安全問題...

def show 
    style = params[:style] || :medium 

    thing = Model.find(params[:id]) 

    path = "#{Rails.root}/public#{thing.image_url(style)}" 
    content_type = thing.image.content_type || 'image/png' 
    send_file path, type: content_type, disposition: 'inline' 
end 

我們使用ActionController Parameters其他地方有很大的影響;但我看不出如何將參數選項「白名單」?我見過的每一處都說要使用模型驗證器,但這是假設我正在提交一個參數來更新模型,而我並不是這樣。

我知道我可以做這樣的事情:

return head :not_found unless %w(small medium large).include? style 

這是最好的辦法嗎?

回答

4

首先,您需要定義一個常量白名單,列出所有有效的style值(我認爲size_type是一個更明確的名稱)。 (注意符號/字符串比較)。

然後,你要麼返回404,如果params[:style]沒有在白名單中的值包括在內或你退回到'medium'

style = Model::AVAILABLE_SIZE_TYPES.include?(params[:style]) ? params[:style] || Model::AVAILABLE_SIZE_TYPES.first 

就個人而言,我不喜歡的用戶的輸入回退。他們做了錯誤的事情(操縱URL,改變了表單中的值等),他們應該得到一個錯誤頁面。

我暗示常量是在模型中定義的,但它不應該存在,因爲它與業務邏輯無關,而與模型的顯示有關。如果您有ModelDecorator,請在此處定義它。

+2

與此一起去,[看起來](https://github.com/thoughtbot/paperclip#post - 處理)使用紙夾模型可能設置爲'has_attached_file:avatar,styles:{thumb:[「32x32#」,::png]}'所以我可能會建議在那裏使用常量'AVAILABLE_SIZE_TYPES = {thumb :[「32x32#」,::png]}''has_attached_file:avatar,styles:AVAILABLE_SIZE_TYPES'然後'Model :: AVAILABLE_SIZE_TYPES.has_key?(params [:style])'(再次觀看字符串/符號)... single來源o如果你以後添加了':tiny',它已經被更新了。 –

+1

擴展@SimpleLime的說法:你可以有一個常量,比如說'IMAGE_CONFIGURATIONS = {small:['32x32#',:png]} .freeze',然後定義AVAILABLE_SIZE_TYPES = IMAGE_CONFIGURATIONS.keys'或者甚至有一個ImageConfiguration '對象(參見以下優秀文章的「提取價值對象」部分https://www.toptal.com/ruby-on-rails/decoupling-rails-components) – MrYoshiji

4

爲了這個目的,我寫了一個擴展爲ActionController::Parameters的gem:白名單參數值。它簡單輕便。你會使用這樣的:

def model_params 
    params.require(:model).permit(:style, :other_attribute).allow(style: %w[small medium large]) 
end 

希望你覺得它有用

https://github.com/msimonborg/allowable

+0

這很酷! – Nick

+0

@Nick謝謝! :) –

+1

@ m.simonborg很好的工作!雖然,我認爲'{'a'=> 1} .allow(a:1)'應該可以工作,但是你的代碼忽略了散列是常規散列或者HashWithIndifferentAccess的事實。另外,'{a:1,'a'=> 2} .allow(a:[1,2])'會允許這兩個鍵,我無法根據鍵的類型來限制它。 (我沒有測試過,只是看了源代碼) – MrYoshiji

相關問題