Ruby on rails Rails 3嵌套属性:如何将匹配记录分配给父模型,而不是每次都创建新记录?
以下是基本设置: 我有一个Ruby on rails Rails 3嵌套属性:如何将匹配记录分配给父模型,而不是每次都创建新记录?,ruby-on-rails,ruby-on-rails-3,nested-forms,nested-attributes,Ruby On Rails,Ruby On Rails 3,Nested Forms,Nested Attributes,以下是基本设置: 我有一个订单型号。一个订单有一个地址,它接受:Address的嵌套属性 我有一个基本的订单,要求用户输入地址。这是通过的嵌套字段处理的。一切都很好-新地址都经过验证并分配得很好 但是,问题是,它每次都会创建一个新的地址,即使地址已经存在,并且具有相同的属性 我想修改该行为,以便如果用户输入的地址与现有地址的所有属性匹配,订单将现有地址分配给自身,而不是创建新地址 我尝试过的方法有: 在控制器中,尝试查找具有嵌套属性的现有地址记录(params[:order][:Address\
订单
型号。一个订单
有一个地址
,它接受:Address的嵌套属性
我有一个基本的订单,要求用户输入地址。这是通过
的嵌套字段处理的。一切都很好-新地址都经过验证并分配得很好
但是,问题是,它每次都会创建一个新的地址
,即使地址
已经存在,并且具有相同的属性
我想修改该行为,以便如果用户输入的地址与现有地址
的所有属性匹配,订单将现有地址
分配给自身,而不是创建新地址
我尝试过的方法有:
params[:order][:Address\u attributes]
)。如果存在匹配项,请删除所有嵌套属性并将其替换为params[:order][:address\u id]
嵌套的属性,而是覆盖模型中的地址=
方法,然后使用控制器根据参数创建一个新的地址
,然后将其交给模型
提前谢谢。你试过这样的东西吗
class Order < ActiveRecord::Base
# [..]
before_save :replace_existing_address!
def replace_existing_address!
db_address = Address.where(:city => self.address.city,
:street => self.address.street,
:number => self.address.number).first
self.address = db_address if db_address
end
end
类顺序self.address.city,
:street=>self.address.street,
:number=>self.address.number)。首先
self.address=db\u地址(如果是db\u地址)
结束
结束
既然我问这个问题是为了调查解决问题的好方法,我想我会提供我目前使用的解决方案以及发表评论的依据
在控制器中:
@new_address = Address.new( params[:order][:address] )
@order.address = new_address
@order.update_attributes( params[:order] )
def address=( address )
return unless address and address.is_a? Address
duplicate_address = Address.where( address_1: address.address_1,
address_2: address.address_2,
[etc. etc.] ).first
if duplicate_address
self.address_id = duplicate_address.id
else
address.save
self.address_id = address.id
end
end
在模型中:
@new_address = Address.new( params[:order][:address] )
@order.address = new_address
@order.update_attributes( params[:order] )
def address=( address )
return unless address and address.is_a? Address
duplicate_address = Address.where( address_1: address.address_1,
address_2: address.address_2,
[etc. etc.] ).first
if duplicate_address
self.address_id = duplicate_address.id
else
address.save
self.address_id = address.id
end
end
正如你所说,这确实是一个:有一个关系,而不是一个:有很多,你不需要像在自己的答案中那样明确地分配地址。毕竟,这就是接受嵌套属性的目的。这条线本身应该起作用:
@order.update_attributes( params[:order] )
如果不存在,则应创建新地址,并更新现有地址
您的解决方案可能会起作用,但它a)不会利用accepts_nested_属性,b)会在数据库中留下大量孤立地址。是的,这与我使用的重写属性设置器非常相似。我喜欢这种方法,尽管我可能会在创建前将其设置为
,这样它就不会在每次修改订单时查询数据库。在接受之前,我想看看人们使用了哪些其他方法,但这似乎是一个非常好的解决方案。而且名称也不完美,可能是reuse\u address代码>,我现在不认为孤立地址有什么好处,但这如何解决最初的问题,即这种方法将导致数据库中有多个相同的地址(除了ID之外)?据我所知,接受嵌套属性
不检查是否存在具有相同属性的记录,它只检查是否存在具有相同ID的记录。由于地址在通过订单创建时没有ID,因此每次都会产生一个新地址。