[英]Nested _destroy attribute with Mongoid and strong_parameters
[英]Unable to update or create records using POST with strong_parameters and nested attributes
当我从表单中过帐时,我无法弄清楚为什么我的数据库记录没有得到更新或创建了新记录。
我能够手动填充数据库并创建关系:
contact = Contact.first
command = Command.find(3)
contact.host_notification_commands << command
而且我还可以在我的表单中加载此数据信息。 我不知道如何更新或添加新记录。 到目前为止,我尝试过的一切都失败了。
我有3个模型Command
, Contact
和Joined CommandsContact
。 commands_contacts
联接表具有一个额外的属性:notification_type
,可以将其设置为主机或服务 ,并且我的Contact
模型设置了2个额外的关系,我可以访问:host_notification_commands
和:service_notification_commands
。 这使我能够执行诸如Contact.fist.host_notification_commands
或Contact.find(3).service_notification_commands.
似乎没有UPDATE
或INSERT
查询从控制器触发,当我执行正确的POST时,我不知道如何调试它。
楷模
class Command < ActiveRecord::Base
has_many :commands_contacts
has_many :contacts, :through => :commands_contacts
end
class Contact < ActiveRecord::Base
has_many :commands_contacts
has_many :commands, :through => :commands_contacts
has_many :host_notification_commands, -> { where commands_contacts: { :notification_type => 'host' } },
:through => :commands_contacts,
:class_name => 'Command',
:source => :command
has_many :service_notification_commands, -> { where commands_contacts: { notification_type: 'service' } },
:through => :commands_contacts,
:class_name => 'Command',
:source => :command
accepts_nested_attributes_for :commands, :host_notification_commands, :service_notification_commands
end
class CommandsContact < ActiveRecord::Base
belongs_to :command
belongs_to :contact
accepts_nested_attributes_for :command
end
在此之后,一切都崩溃了。
控制者
由于我正在使用accepts_nested_attributes_for
,因此我必须将_attributes
附加到嵌套对象的名称- :host_notification_commands
和:service_notification_commands
。 我将更改表单以这种方式提交,但是出于示例目的,简单的重新分配有效。
def update
contact = Contact.find_by_id(params[:id])
contact.update(safe_params)
end
private
def safe_params
params[:contact][:host_notification_commands_attributes] = params[:contact][:host_notification_commands]
params[:contact][:service_notification_commands_attributes] = params[:contact][:service_notification_commands]
params.require(:contact)
.permit(:contact_name, :host_notification_commands_attributes => [:id, :command_name, :command_line, :command_description],
:service_notification_commands_attributes => [:id, :command_name, :command_line, :command_description])
end
更新现有记录结果:
#<ActiveRecord::RecordNotFound: Couldn't find Command with ID=2 for Contact with ID=1>
当然不存在! 我正在尝试建立这种关系!
添加一个新的,我得到:
#<ActiveRecord::RecordNotFound: Couldn't find Command with ID=1 for Contact with ID=>
完全正确。 用户甚至还没有创建,并且还没有通过命令建立关系,为什么Rails试图找到它?
我也没有在Rails控制台中看到任何更新或插入查询,因此我想它甚至没有达到这一点...
D, [2015-01-20T18:01:30.336669 #95542] DEBUG -- : (0.1ms) BEGIN
D, [2015-01-20T18:01:30.338971 #95542] DEBUG -- : Command Load (0.3ms) SELECT `commands`.* FROM `commands` INNER JOIN `commands_contacts` ON `commands`.`id` = `commands_contacts`.`command_id` WHERE `commands_contacts`.`contact_id` = 1 AND `commands_contacts`.`notification_type` = 'host' AND `commands`.`id` IN (1, 3)
D, [2015-01-20T18:01:30.340555 #95542] DEBUG -- : Command Load (0.2ms) SELECT `commands`.* FROM `commands` INNER JOIN `commands_contacts` ON `commands`.`id` = `commands_contacts`.`command_id` WHERE `commands_contacts`.`contact_id` = 1 AND `commands_contacts`.`notification_type` = 'service' AND `commands`.`id` IN (4, 2)
D, [2015-01-20T18:01:30.341501 #95542] DEBUG -- : (0.1ms) ROLLBACK
#<ActiveRecord::RecordNotFound: Couldn't find Command with ID=2 for Contact with ID=1>
Completed 200 OK in 11ms (Views: 0.4ms | ActiveRecord: 0.9ms)
我在这里想念什么?
编辑:我想我可以放弃使用strong_parameters
的想法,解析所有POST参数,然后手动填充数据库,但是那不是Rails-y。
编辑2:包括发布到控制器的参数。
数据以params[:contact]
形式输入
{
"contact_name" => "joe-user",
"host_notification_commands" => [
[0] {
"id" => 1,
"command_name" => "host-notify-by-email",
"command_line" => "/usr/local/bin/host-notify",
"command_description" => "Host Alert",
"created_at" => "2015-01-19T17:24:12.000Z",
"updated_at" => "2015-01-21T03:29:03.000Z"
},
[1] {
"id" => 2,
"command_name" => "host-notify-by-pager",
"command_line" => "/usr/local/bin/host-notify-pager",
"command_description" => "Host Alert by Pager",
"created_at" => "2015-01-19T17:24:33.000Z",
"updated_at" => "2015-01-19T17:24:33.000Z"
}
],
"service_notification_commands" => [
[0] {
"id" => 4,
"command_name" => "service-notify-by-email",
"command_line" => "/usr/local/bin/service-notify",
"command_description" => "Service Alert",
"created_at" => "2015-01-19T17:24:44.000Z",
"updated_at" => "2015-01-19T17:24:44.000Z"
}
]
}
经过strong_parameters
之后,它变成了:
本质上是一样的,只是剥离了created_at
和updated_at
并将_attributes
附加到属性名称之后,因此它与accept_nested_attributes_for
一起accept_nested_attributes_for
{
"contact_name" => "joe-user",
"host_notification_commands_attributes" => [
[0] {
"id" => 1,
"command_name" => "host-notify-by-email",
"command_line" => "/usr/local/bin/host-notify",
"command_description" => "Host Alert"
},
[1] {
"id" => 2,
"command_name" => "host-notify-by-pager",
"command_line" => "/usr/local/bin/host-notify-pager",
"command_description" => "Host Alert by Pager"
}
],
"service_notification_commands_attributes" => [
[0] {
"id" => 4,
"command_name" => "service-notify-by-email",
"command_line" => "/usr/local/bin/service-notify",
"command_description" => "Service Alert"
}
]
}
编辑#3:我已启用MySQL查询日志记录,但我根本看不到执行UPDATE
/ INSERT
查询。 我如何调试为什么contact.update(safe_params)
没有做任何事情?
编辑#4:作为没有AngularJS或POST的简单测试,我做了一个简单的rake任务,该任务定义了JSON对象并尝试更新db。 我遇到了同样的问题,因此我非常确信该问题在我的模型中某处...但是在哪里?
构建表单并使用nested_fields_for
表单结构时,构建正确。 因此,理想情况下,您将首先尝试以“老式方式”执行此操作,然后检查推送到服务器的内容并进行模拟。
因此,通常我不会手动执行此操作,但我会维护一个gem来处理嵌套表单(茧),因此,如果我没有记错的话, accepts_nested_attributes
起作用,参数必须如下所示:
{
"contact_name" => "joe-user",
"host_notification_commands_attributes" => {
"0" => {
"id" => 1,
"command_name" => "host-notify-by-email",
"command_line" => "/usr/local/bin/host-notify",
"command_description" => "Host Alert"
},
"1" => {
"id" => 2,
"command_name" => "host-notify-by-pager",
"command_line" => "/usr/local/bin/host-notify-pager",
"command_description" => "Host Alert by Pager"
}
},
"service_notification_commands_attributes" => {
"0" => {
"id" => 4,
"command_name" => "service-notify-by-email",
"command_line" => "/usr/local/bin/service-notify",
"command_description" => "Service Alert"
},
"12342233444444" => {
"command_name" => "service-notify-by-email",
"command_line" => "/usr/local/bin/service-notify",
"command_description" => "Service Alert"
}
}
}
因此, .._attributes
不应包含数组,而应包含哈希。 关键在于(现有)数组中的位置,我认为。 在茧中,我用从当前时间得出的一些大数字填充此虚拟索引 。 我假设此顺序应与该关系的默认顺序相对应。 但是,如果您将“ id”字段交给您,那么Rails也可能会使用它。 不确定。 要销毁现有元素,您必须设置_destroy
属性(并在强参数中也允许它)。
恕我直言,新项目的id
应该为空,否则Rails会假定该项目存在(因为通常不会在客户端生成ID)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.