我有两个型号
Address.rb belongs_to :zip accepts_nested_attributes_for :zip Zip.rb has_many :addresses
在新地址的表单上我也创建了一个Zip。但我想检查插入的Zip是否已经存在。如果是这样,它应该返回现有的Zip,如果没有,它应该创建一个新的
AddressController def new @address = Address.new @address.build_zip end
我在StackOverFlow上看到一个类似的question而没有我正在跳的答案......有人建议:
before_create :check_zip_exists def check_zip_exists @zip = Zip.find_by_cp1_and_cp2(self.cp1, self.cp2) if @zip!=nil # end end
#
应该将现有的Zip与地址相关联而不是创建一个新的?
答案 0 :(得分:2)
尝试类似:
zip = Zip.where(field: value).first_or_create
<强>更新强>
当您使用accepts_nested_attributes_for :zip
时,内部发生的事情是生成名为zip_attributes=(attributes)
的公共方法。
此方法调用私有方法(取决于关系是集合还是单个对象),在您的情况下,调用的私有方法是assign_nested_attributes_for_one_to_one_association
因此,您可以覆盖zip_attributes=(attributes)
模型中的public_method Address
来替换正常行为:
def zip_attributes=(attributes)
self.zip = Zip.where(attributes).first_or_create #you can change attributes to be the fields that you need to find the correct zip
end
更新2
def zip_attributes=(attributes)
cp1 = attributes.delete(:cp1)
cp2 = attributes.delete(:cp2)
self.zip = Zip.where(cp1: cp1, cp2: cp2).first_or_create(attributes)
end
答案 1 :(得分:2)
这样做的方式如下:
Address.rb belongs_to :zip accepts_nested_attributes_for :zip, :reject_if => :check_zip_exists private def check_zip_exists(attributed) cp1 = attributed['cp1'] cp2 = attributed['cp2'] zip = Zip.where(:cp1=>cp1, :cp2=>cp2).first if zip.nil? return false else self.zip_id = zip.id end end