Rails 5 - 更新时手动向控制器中的参数添加属性
Rails 5 - Manually add attribute to parameters in controller when updating
我正在尝试在完成表单后手动向控制器中的参数添加一个附加属性。参数似乎包含在 中,这似乎阻止我更改参数。
控制器:
class ActualsController < SignedInController
...
def update
respond_to do |format|
facesheet = actual_params[:facesheet]
#trying to manually add attribute
actual_params.merge(:file_name => 'ted.png')
new_params = actual_params.except(:facesheet)
if @actual.update(new_params)
format.html { redirect_to action: 'show', id:@actual.id, notice: 'Actual was successfully updated.' }
format.json { render :show, status: :ok, location: @actual }
else
format.html { render :edit }
format.json { render json: @actual.errors, status: :unprocessable_entity }
end
end
end
...
end
"new_params" 来自控制台
<ActionController::Parameters {"encounter_type_id"=>"1", "physician_id"=>"669", "insurance_id"=>"1182", "time_start"=>"05:00", "time_end"=>"07:00", "date_start"=>"2017-08-02", "date_end"=>"2017-08-02", "facility_id"=>"1", "med_rec_num"=>"1244", "patient_name_first"=>"Bob", "patient_name_last"=>"Smith", "patient_name_middle_initial"=>"H", "patient_dob"=>"2000-02-05", "note"=>"", "is_complete"=>"0", "procedure_ids"=>["", "300"]} permitted: true> -Thanks for your help on this.
来自控制台的“@actual”
#<Actual id: 18, encounter_id: 4, provider_id: 7, encounter_type_id: 1, physician_id: 669, facility_id: 1, insurance_id: 1182, group_id: nil, datetime_start_utc: "2017-08-02 10:00:00", datetime_end_utc: "2017-08-02 12:00:00", payer: nil, med_rec_num: "1244", patient_name_first: "Bob", patient_name_last: "Smith", patient_name_middle_initial: "H", patient_dob: "2000-02-05", finclass: nil, is_valid: nil, is_complete: false, image_location: nil, note: "", created_at: "2017-08-18 13:30:58", updated_at: "2017-08-18 16:01:28">
您正在使用 merge
其中
Returns a new ActionController::Parameters
with all keys from other_hash
merged into current hash
并且您没有将新的 ActionController::Parameters
存储到任何东西中。您可以改用 merge!
which
Returns current ActionController::Parameters
instance with other_hash
merged into current hash.
actual_params.merge!(:file_name => 'ted.png')
如果 actual_params
是你控制器上的一个方法而不是一个对象(这个名字第一次给我,但看到模型名称可能是 Actual
,一个方法现在更有意义) ,您需要将 return 值存储到新的散列中以使用:
new_params = actual_params.merge(:file_name => 'ted.png')
new_params = new_params.except(:facesheet)
@actual.update(new_params)
这是因为每次调用定义如下的方法时:
def actual_params
params.require(:actual).permit(:factsheet, *whatever_else)
end
它每次都会 return 生成一个新的、不同的 ActionController::Parameters
,因此如果您不将其保存在任何地方,则对其进行修改仍然无法正常工作
一般来说,将传入参数视为不可变是一种很好的做法。它使控制器代码的调试和推理变得更加简单。
您可以采取一些技巧来避免对参数进行修改。
使用块:
# this works for .new and .create as well
updated = @actual.update(actual_params) do |a|
a.foo = current_user.foo
a.b = params.fetch(:foo, "some default")
end
使用组合创建安全参数方法。
def common_params
[:name, :title]
end
def create_params
params.require(:model_name)
.permit(*common_params, :foo)
end
def update_params
params.require(:model_name)
.permit(*common_params, :bar)
end
使用 .except
可能会有风险,因为白名单比黑名单更好,因为您可能会忘记将未来的属性添加到黑名单。
尝试将参数列入白名单而不是使用 .except
也尝试使用 .permit() 将所需参数列入白名单
试试
private
def post_params
params.require(:post).permit(:some_attribute).merge(user_id: current_user.id)
end
我正在尝试在完成表单后手动向控制器中的参数添加一个附加属性。参数似乎包含在 中,这似乎阻止我更改参数。
控制器:
class ActualsController < SignedInController
...
def update
respond_to do |format|
facesheet = actual_params[:facesheet]
#trying to manually add attribute
actual_params.merge(:file_name => 'ted.png')
new_params = actual_params.except(:facesheet)
if @actual.update(new_params)
format.html { redirect_to action: 'show', id:@actual.id, notice: 'Actual was successfully updated.' }
format.json { render :show, status: :ok, location: @actual }
else
format.html { render :edit }
format.json { render json: @actual.errors, status: :unprocessable_entity }
end
end
end
...
end
"new_params" 来自控制台
<ActionController::Parameters {"encounter_type_id"=>"1", "physician_id"=>"669", "insurance_id"=>"1182", "time_start"=>"05:00", "time_end"=>"07:00", "date_start"=>"2017-08-02", "date_end"=>"2017-08-02", "facility_id"=>"1", "med_rec_num"=>"1244", "patient_name_first"=>"Bob", "patient_name_last"=>"Smith", "patient_name_middle_initial"=>"H", "patient_dob"=>"2000-02-05", "note"=>"", "is_complete"=>"0", "procedure_ids"=>["", "300"]} permitted: true> -Thanks for your help on this.
来自控制台的“@actual”
#<Actual id: 18, encounter_id: 4, provider_id: 7, encounter_type_id: 1, physician_id: 669, facility_id: 1, insurance_id: 1182, group_id: nil, datetime_start_utc: "2017-08-02 10:00:00", datetime_end_utc: "2017-08-02 12:00:00", payer: nil, med_rec_num: "1244", patient_name_first: "Bob", patient_name_last: "Smith", patient_name_middle_initial: "H", patient_dob: "2000-02-05", finclass: nil, is_valid: nil, is_complete: false, image_location: nil, note: "", created_at: "2017-08-18 13:30:58", updated_at: "2017-08-18 16:01:28">
您正在使用 merge
其中
Returns a new
ActionController::Parameters
with all keys fromother_hash
merged into current hash
并且您没有将新的 ActionController::Parameters
存储到任何东西中。您可以改用 merge!
which
Returns current
ActionController::Parameters
instance withother_hash
merged into current hash.
actual_params.merge!(:file_name => 'ted.png')
如果 actual_params
是你控制器上的一个方法而不是一个对象(这个名字第一次给我,但看到模型名称可能是 Actual
,一个方法现在更有意义) ,您需要将 return 值存储到新的散列中以使用:
new_params = actual_params.merge(:file_name => 'ted.png')
new_params = new_params.except(:facesheet)
@actual.update(new_params)
这是因为每次调用定义如下的方法时:
def actual_params
params.require(:actual).permit(:factsheet, *whatever_else)
end
它每次都会 return 生成一个新的、不同的 ActionController::Parameters
,因此如果您不将其保存在任何地方,则对其进行修改仍然无法正常工作
一般来说,将传入参数视为不可变是一种很好的做法。它使控制器代码的调试和推理变得更加简单。
您可以采取一些技巧来避免对参数进行修改。
使用块:
# this works for .new and .create as well
updated = @actual.update(actual_params) do |a|
a.foo = current_user.foo
a.b = params.fetch(:foo, "some default")
end
使用组合创建安全参数方法。
def common_params
[:name, :title]
end
def create_params
params.require(:model_name)
.permit(*common_params, :foo)
end
def update_params
params.require(:model_name)
.permit(*common_params, :bar)
end
使用 .except
可能会有风险,因为白名单比黑名单更好,因为您可能会忘记将未来的属性添加到黑名单。
尝试将参数列入白名单而不是使用 .except
也尝试使用 .permit() 将所需参数列入白名单
试试
private
def post_params
params.require(:post).permit(:some_attribute).merge(user_id: current_user.id)
end