所以我正在研究在rails中构建用户模型,这个用户模型将具有相关的电子邮件地址模型。电子邮件地址模型对电子邮件具有唯一性约束。现在我设置它,以便用户accept_nested_attributes_for:email_address。这在创建时效果很好,但在更新时我收到此错误:
ActiveRecord::JDBCError: org.postgresql.util.PSQLException:
ERROR: duplicate key value violates unique constraint
"index_email_addresses_on_email"
我可以通过在rails控制台中执行此操作来重新创建此错误:
u = User.create(:name => "foo", :new_password => "Passw0rd",
:email_address_attributes => {:email => "foo@bar.com"})
u.update({:name => "new name",
:email_address_attributes => {:email => "foo@bar.com"}})
如何在不关心email_address的情况下更新名称。哪个没改变?
其他一些注释和代码:
我在电子邮件中为我的email_address编制索引,而我正在使用rails 4。
class User < ActiveRecord::Base
belongs_to :email_address
validates :email_address, :presence => true
accepts_nested_attributes_for :email_address
end
class EmailAddress < ActiveRecord::Base
validates_format_of :email, :with => RFC822::EmailAddress
validates :email, :presence => true
has_one :user
end
答案 0 :(得分:1)
如果您不想验证除创建之外的电子邮件地址,您可以将其添加到验证中:
validates :email_address, presence: true, on: :create
答案 1 :(得分:1)
以这种方式更新email_address_attributes
时,实际上是在为email_address
添加新的user
对象。您需要将电子邮件地址的ID作为属性传递,即:
u.update({:name => "new name",
:email_address_attributes => {:id => u.email_address.id, :email => "foo@bar.com"}})
或者,您可以使用其他更新语句更新用户的电子邮件地址
u.update({:name => "new name"})
u.email_address.update({:email => "foo@bar.com"})
对于您的控制器,您只需将电子邮件地址的:id
字段添加为允许的参数。
def user_params
params.require(:user).permit(:name, email_address_attributes: [:id, :email])
end
Strong Parameters Rails Guide中有关于强参数的更多信息。查看More Example section以获得与您类似的设置。
答案 2 :(得分:1)
在“accepts_nested_attributes_for”中使用“:update_only”选项,如下所示:
accepts_nested_attributes_for :email_address, :update_only => true
这样,活动记录将更新子记录(如果已存在),而不是创建新记录。这应该照顾独特的约束。