Rails 5:update_attributes 具有唯一约束
Rails 5: update_attributes with unique constraints
我正在尝试在控制器中调用 find_or_initialize_by
,如下所示:
@lead = Lead.find_or_initialize_by(external_id: lead['external_id'])
@lead.update_attributes(lead)
一切都很好,但我的问题是 lead
可以而且应该包含一些对我的模型有独特约束的信息:
validates :address, uniqueness: { scope: [:address, :city, :state, :zip] }
validates :voter_id, uniqueness: true
validates :external_id, uniqueness: true
validates :email, uniqueness: true, allow_blank: true, allow_nil: true
validates_presence_of :first_name, :last_name, :address, :city, :state, :zip, :source, :status
因此,当数据库中已存在潜在客户时,update_attributes
失败,因为哈希包含与记录已经包含的相同信息(加上非唯一差异):
ActiveRecord::RecordInvalid (Validation failed: Address has already been taken, Voter has already been taken, External has already been taken):
我如何传递这个散列并让 Rails 保存它,无论它是新的(由 initialize_by
制作)还是现有的(由 find
制作)同时保持所有验证?
对于 Rails 5 使用 update_attribute instead of update_attributes.
它更新单个属性并保存记录,而无需经过正常的验证过程。
注意:update_attribute
从给出的问题代码中一次只更新一个属性,我认为它对你有用。
如果这个方法不适合你,你也可以用.update_columns
found here.
@lead = Lead.find_or_initialize_by(external_id: lead['external_id'])
@lead.attributes = lead
@lead.save(validate: false)
这应该可以解决问题
不确定你为什么要绕过你的验证,这会在以后咬你。
Api 链接:
内部,update_attributes
calls assign_attributes
,它分配给定的属性并覆盖现有值(如果它们不同)。但是,如果以前分配过相同的值,则此属性不会被视为已更改,因此不会包含在更新的查询中。
如果一切正常,您的唯一性验证应该不会失败 - 无论是新记录还是现有记录。我假设,还有其他一些怪癖(在提供的有关您的上下文的信息中不可见)导致这些错误,建议不要简单地禁用验证。
我正在尝试在控制器中调用 find_or_initialize_by
,如下所示:
@lead = Lead.find_or_initialize_by(external_id: lead['external_id'])
@lead.update_attributes(lead)
一切都很好,但我的问题是 lead
可以而且应该包含一些对我的模型有独特约束的信息:
validates :address, uniqueness: { scope: [:address, :city, :state, :zip] }
validates :voter_id, uniqueness: true
validates :external_id, uniqueness: true
validates :email, uniqueness: true, allow_blank: true, allow_nil: true
validates_presence_of :first_name, :last_name, :address, :city, :state, :zip, :source, :status
因此,当数据库中已存在潜在客户时,update_attributes
失败,因为哈希包含与记录已经包含的相同信息(加上非唯一差异):
ActiveRecord::RecordInvalid (Validation failed: Address has already been taken, Voter has already been taken, External has already been taken):
我如何传递这个散列并让 Rails 保存它,无论它是新的(由 initialize_by
制作)还是现有的(由 find
制作)同时保持所有验证?
对于 Rails 5 使用 update_attribute instead of update_attributes.
它更新单个属性并保存记录,而无需经过正常的验证过程。
注意:update_attribute
从给出的问题代码中一次只更新一个属性,我认为它对你有用。
如果这个方法不适合你,你也可以用.update_columns
found here.
@lead = Lead.find_or_initialize_by(external_id: lead['external_id'])
@lead.attributes = lead
@lead.save(validate: false)
这应该可以解决问题 不确定你为什么要绕过你的验证,这会在以后咬你。
Api 链接:
内部,update_attributes
calls assign_attributes
,它分配给定的属性并覆盖现有值(如果它们不同)。但是,如果以前分配过相同的值,则此属性不会被视为已更改,因此不会包含在更新的查询中。
如果一切正常,您的唯一性验证应该不会失败 - 无论是新记录还是现有记录。我假设,还有其他一些怪癖(在提供的有关您的上下文的信息中不可见)导致这些错误,建议不要简单地禁用验证。