Ruby on rails Rails合并(和手动分配)分配nil
我正在尝试使用Rails 5.1中的强参数在控制器中创建一个模型(与以前的强参数有所不同)。但是,当我检查参数时,合并的参数不存在,并且我得到了一个禁止的属性错误,可以追溯到下面的Model.new行。模型中唯一的事情就是验证所有属性是否存在Ruby on rails Rails合并(和手动分配)分配nil,ruby-on-rails,strong-parameters,ruby-on-rails-5.1,rails-models,Ruby On Rails,Strong Parameters,Ruby On Rails 5.1,Rails Models,我正在尝试使用Rails 5.1中的强参数在控制器中创建一个模型(与以前的强参数有所不同)。但是,当我检查参数时,合并的参数不存在,并且我得到了一个禁止的属性错误,可以追溯到下面的Model.new行。模型中唯一的事情就是验证所有属性是否存在 class ModelController < ApplicationController before_action :application_controller_action def create @model = Model
class ModelController < ApplicationController
before_action :application_controller_action
def create
@model = Model.new(strong_params)
if @model.valid?
result = @model.save
else
render html: 'MODEL NOT VALID'
end
render html: 'DONE'
end
private
def strong_params
# attr_1 and attr_2 are set in the application controller and are available here.
params.require(:model).permit(:name, :attribute_1, :attribute_2).merge(attribute_1: @attr_1, attribute_2: @attr_2)
# Inserting the following two lines causes a ForbiddenAttributesError
puts params.inspect # DOES NOT INCLUDE @attr_1 and/or @attr_2
return params
end
更新:
好的,我在故障排除中发现了一些奇怪的错误。合并似乎没有正常工作,尽管我确信它在某一点上是正确的
我检查的第一件事是@attr_1和@attr_2,它们肯定已经设置好了
出于故障排除的目的,我已将“应用程序启动前”操作简化为:
def application_before_action
@attr_1 = Model.first
@attr_2 = Model.last
使用上面的代码,检查params对象,然后在require().permit()之后返回它,我得到了一个禁止属性错误(没有什么指示)。如果我删除这些行,我会从模型中得到一个缺失属性错误,表明@attr_1和@attr_2缺失
更新2
更改了问题的标题,因为我可能在故障排除过程中感到困惑。我认为问题只是合并分配了零。。。但奇怪的是,(我原来)建议的手工作业和这里的另一个答案也是如此。属性键在那里,但它们被分配为零。另外,注意到我的示例使用的是一个模型,而实际上有两个模型,Model1和Model2。我正在将值从Model1分配到Model2
下面是错误的更好演示:
def create
puts '0:'
puts @model1.inspect
puts '1:'
puts strong_params.inspect
@model2 = Model2.new(strong_params) do |m|
m.user_id = @attr_1
m.account_number = @attr_2
end
puts '3:'
puts @model2.inspect
if @model2.valid?
result = @model2.save
render html: 'SUCCESS' and return
else
render html: @model2.errors.full_messages and return
end
end
控制台中的输出:
0:
#<Model1 id: 29, attribute_1: 'test_value_1', attribute_2: 'test_value_2', created_at: "2018-08-15 03:55:08", updated_at: "2018-08-15 04:05:01">
1:
<ActionController::Parameters {"name"=>"test_name", "attribute_1"=>nil, "attribute_2"=>nil} permitted: true>
3:
#<Model2 id: nil, name: 'test_name', attribute_1: nil, attribute_2: nil, created_at: nil, updated_at: nil>
0:
#
1:
允许的“测试名称”、“属性\u 1”=>nil、“属性\u 2”=>nil}:true>
三:
#
显然,nil id和时间戳是因为模型还没有保存
html model2.errors.full_消息为:[“attribute_1不能为空”,“attribute_2不能为空”]
解决方案
以前,我来自纯ruby环境,对于模型的ActiveRecord默认访问器,我是错误的。删除访问器似乎已经解决了这个问题。您可以一个接一个地分配奇数值,而不是乱搞参数散列:
class ModelController < ApplicationController
before_action :application_controller_action
def create
@model = Model.new(strong_params) do |m|
m.attribute_1 = @attr_1
m.attribute_2 = @attr_2
end
if @model.valid?
result = @model.save
else
render html: 'MODEL NOT VALID'
end
# don't do this it will just give a double render error
render html: 'DONE'
end
private
private
def strong_params
params.require(:model).permit(:name, :attribute_1, :attribute_2)
end
end
或者只是:
def strong_params
# attr_1 and attr_2 are set in the application controller and are available here.
params.require(:model).permit(:name, :attribute_1, :attribute_2)
.merge(attribute_1: @attr_1, attribute_2: @attr_2)
end
您可以一个接一个地分配奇数值,而不是乱搞参数散列:
class ModelController < ApplicationController
before_action :application_controller_action
def create
@model = Model.new(strong_params) do |m|
m.attribute_1 = @attr_1
m.attribute_2 = @attr_2
end
if @model.valid?
result = @model.save
else
render html: 'MODEL NOT VALID'
end
# don't do this it will just give a double render error
render html: 'DONE'
end
private
private
def strong_params
params.require(:model).permit(:name, :attribute_1, :attribute_2)
end
end
或者只是:
def strong_params
# attr_1 and attr_2 are set in the application controller and are available here.
params.require(:model).permit(:name, :attribute_1, :attribute_2)
.merge(attribute_1: @attr_1, attribute_2: @attr_2)
end
您可以在合并之前转换为哈希
params.require(:model).permit(:name).to_h.merge(attribute_1: @attr_1, attribute_2: @attr_2)
您必须非常确定您正在分配非用户输入,否则您将否定强参数的用途 您可以在合并之前转换为哈希
params.require(:model).permit(:name).to_h.merge(attribute_1: @attr_1, attribute_2: @attr_2)
您必须非常确定您正在分配非用户输入,否则您将否定强参数的用途
@attr_1
和@attr_2
来自哪里?其中是:应用程序\u控制器\u操作
防御?strong\u参数
只是一种常规方法。在您的代码中调用strong_params
之前,不会执行它。我认为问题在于应用程序\u控制器\u操作
从未执行过(或者它没有设置@attr\u 1
和@attr\u 2
)。你考虑了吗?@ USE58466我假设你在控制器中收到了<代码>名称<代码>,但是你如何得到<代码> @ Tracy1和<代码> @ Trace2。他们也是请求的一部分吗?很抱歉,我正忙着排除故障。请参阅更新。attr_1和attr_2不是请求的一部分,它们是在before_操作(在应用程序控制器中)中设置的,并且“意味着”要添加到params散列中。奇怪的是,它甚至不允许我在不使用散列的情况下手动创建对象。禁用强参数会阻止这种情况发生吗?@user58446如果您在允许后第二次重写属性,则根本没有理由允许它们。我会把它们排除在外。此外,您还说,@attr_1
和@attr_2
肯定正在设置。然而,这并不意味着它们不能是nil
。即使是Model.first
和Model.last
如果不存在条目,也可以返回nil
。分配前是否检查了@attr\u 1
和@attr\u 2
的值?@attr\u 1
和@attr\u 2
来自哪里?其中是:应用程序\u控制器\u操作
防御?strong\u参数
只是一种常规方法。在您的代码中调用strong_params
之前,不会执行它。我认为问题在于应用程序\u控制器\u操作
从未执行过(或者它没有设置@attr\u 1
和@attr\u 2
)。你考虑了吗?@ USE58466我假设你在控制器中收到了<代码>名称<代码>,但是你如何得到<代码> @ Tracy1和<代码> @ Trace2。他们也是请求的一部分吗?很抱歉,我正忙着排除故障。请参阅更新。attr_1和attr_2不是请求的一部分,它们是在before_操作(在应用程序控制器中)中设置的,并且“意味着”要添加到params散列中。奇怪的是,它甚至不允许我在不使用散列的情况下手动创建对象。禁用强参数会阻止这种情况发生吗?@user58446如果您在允许后第二次重写属性,则根本没有理由允许它们。我会把它们排除在外。此外,您还说,@attr_1
和@attr_2
肯定正在设置。然而,这并不意味着它们不能是nil
。即使是Model.first
和Model.last
如果不存在条目,也可以返回nil
。在分配之前,您是否检查了@attr_1
和@attr_2
的值?感谢您的诚实:“您的强参数方法不起作用的原因是它在所有可能的方面都被破坏了。”我以为我只是在遵循示例和合并:。无论如何,您的块示例不起作用。我还在恢复活力