簡體   English   中英

Rails 6 - 允許“動態”哈希參數

[英]Rails 6 - permit “dynamic” hash params

這個按鈕當然重定向到 form_for 創建新消息:

<%= link_to "Send message" , new_message_path( :message => { :user_id => @profile.user.id, :category => 1 } ) %>

但我看到這個:

ActiveModel::ForbiddenAttributesError in MessagesController#new

def new

    @message_new = current_user.messages_send.new(params[:message])

end

在我在 Rails 4.0.0 中的舊腳本中,它可以工作......我讀了一些我嘗試在messages_controller 中做到這一點

def message_params
  params.require(:message).permit(:some_params ... ,  :message => {})
end

但仍然沒有任何變化。

一些評論。 我不明白為什么您的代碼允許在message參數的允許屬性內使用message哈希,這似乎是由於對允許參數的工作方式存在誤解。 例子:

class Message
  belongs_to :user

  validates :user, presence: true
  validates :category, presence: true

  # Let's say a Message has `user`, `category`, and `text` attributes
end

# Controller should look something more like this:
def new
  # Using message_params validates params' structure before using it to create an object
  @message = Message.new(message_params)
end

# Syntax: params.require(:object).permit(*permitted_attributes)
def message_params
  # This checks that params[:message].keys is a subset of [:user_id, :category, :text]
  params.require(:message).permit(:user_id, :category, :text)
end

# Permitted params should be structured like this example:
params: { 
  message: {
    user_id:  12,
    category: 1,
    text:     'Eat a plant!'
  }
}
# Note: `user_id`, `category`, and `text` are _permitted_ as params, 
# but their presence in the `message` hash is not required 
# (only the `message` key is required)

# Params like this will raise an error when using `message_params` 
# because `state` isn't defined as permitted in the `message_params` definition:
params: { 
  message: {
    user_id:  12,
    category: 1,
    text:     'Eat a plant!',
    state:    'initial'
  }
}
  • 您的初始代碼只是簡單地調用params[:message]params[:message]的屬性(例如, user_idcategorytext )傳遞給 Message 構造函數,而不對其進行驗證。
    • 這意味着您的初始代碼會嘗試使用您傳遞給它的任何內容來創建對象(例如,當參數為{ message: { goblin: 'Spaghetti! } }它會嘗試將對象創建為Message.new(user_id: current_user.id, goblin: 'Spaghetti!') )。
  • 當您切換到使用強參數時,您切換到調用message_params方法
    • 此方法首先獲取您的參數,它們是一個 ActionController::Parameters 對象。
    • 然后它調用參數對象上的requirepermit方法來驗證參數不包含任何拼寫錯誤或未定義為允許的其他鍵
    • 如果參數不遵循您在message_params定義的結構,它會引發 ActiveModel::ForbiddenAttributesError ,因為您試圖向它傳遞一個不允許的屬性。

建議:

  • 嘗試在 Rails 控制台中使用允許的參數:
     rails console def validate_params(params_hash) params = ActionController::Parameters.new(params_hash) params.require(:message).permit(:user_id, :category, :text) end good_params = { message: { user_id: 14, category: 1 } } validate_params(good_params) => <ActionController::Parameters {"user_id"=>14, "category"=>1} permitted: true> validate_params(good_params.deep_merge(message: { text: 'Spaghetti!' })) => <ActionController::Parameters {"user_id"=>14, "category"=>1, "text"=>"Spaghetti!"} permitted: true> bad_params = good_params.deep_merge(message: { goblin: 'Spaghetti!' }) => {:message=>{:user_id=>14, :category=>1, :goblin=>"Spaghetti!"}} validate_params(bad_params) Unpermitted parameter: :goblin # observe raised error => <ActionController::Parameters {"user_id"=>14, "category"=>1} permitted: true>
  • 嘗試查看關於強參數的 RoR 指南: https : //guides.rubyonrails.org/action_controller_overview.html#strong-parameters

如果有人會搜索答案:

def new

    @message_new = current_user.messages_send.new(message_params) /// not params[:message]

end

而且當然:

def message_params
  params.require(:message).permit(:some_params ... ,  :message => {})
end

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM