Rails 6 - 允许 "dynamic" 散列参数
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
但仍然没有任何改变。
如果有人会搜索答案:
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
一些意见。我不明白为什么您的代码允许在 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]
将消息的属性(例如 user_id
、category
和 text
)传递给 Message 构造函数,而无需验证它们。
- 这意味着您的初始代码会尝试使用您传递给它的 任何内容 创建对象(例如,当参数为
{ message: { goblin: 'Spaghetti! } }
时,它会尝试创建对象如 Message.new(user_id: current_user.id, goblin: 'Spaghetti!')
).
- 当您切换到使用强参数时,您将切换到调用
message_params
方法
建议:
- 尝试在 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
此按钮当然会重定向到 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
但仍然没有任何改变。
如果有人会搜索答案:
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
一些意见。我不明白为什么您的代码允许在 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]
将消息的属性(例如user_id
、category
和text
)传递给 Message 构造函数,而无需验证它们。- 这意味着您的初始代码会尝试使用您传递给它的 任何内容 创建对象(例如,当参数为
{ message: { goblin: 'Spaghetti! } }
时,它会尝试创建对象如Message.new(user_id: current_user.id, goblin: 'Spaghetti!')
).
- 这意味着您的初始代码会尝试使用您传递给它的 任何内容 创建对象(例如,当参数为
- 当您切换到使用强参数时,您将切换到调用
message_params
方法
建议:
- 尝试在 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