Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails:尝试保存现有行,但Rails生成sql insert而不是update 错误_Ruby On Rails_Save_Sql Update_Sql Insert - Fatal编程技术网

Ruby on rails Rails:尝试保存现有行,但Rails生成sql insert而不是update 错误

Ruby on rails Rails:尝试保存现有行,但Rails生成sql insert而不是update 错误,ruby-on-rails,save,sql-update,sql-insert,Ruby On Rails,Save,Sql Update,Sql Insert,当我有一张新唱片时,我没有问题 当我有一个正在尝试更新的现有记录时,会抛出一个异常(见下文) 以下两种Rails代码变体在我希望更新的email_addresses表中有一行时都会引发相同的异常: ret = @email_address.update(email_address_id: @email_address.email_address_id) 我也试过了 ret = @email_address.save 并得到相同的异常 例外 当我有一个想要更新的现有记录时,我得到的错误是 #&

当我有一张新唱片时,我没有问题

当我有一个正在尝试更新的现有记录时,会抛出一个异常(见下文)

以下两种Rails代码变体在我希望更新的email_addresses表中有一行时都会引发相同的异常:

ret = @email_address.update(email_address_id: @email_address.email_address_id)
我也试过了

ret = @email_address.save
并得到相同的异常

例外 当我有一个想要更新的现有记录时,我得到的错误是

#<ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "email_addresses_pkey"
DETAIL:  Key (email_address_id)=(2651) already exists.
: INSERT INTO "email_addresses" ("email_address_id", "email_address", "zipcode", "confirm_token") VALUES ($1, $2, $3, $4) RETURNING "email_address_id">
模型 如果email\u address\u id已经存在于email\u addresses表中,由于

"email_addresses_pkey" PRIMARY KEY, btree (email_address_id)
主键上的隐式约束

我可能可以通过直接在Rails中编写SQL代码来实现这一点,但我希望继续使用Rails代码并理解我做错了什么

我在网上搜索了好几个小时都没有成功。我曾尝试过跟踪rails代码,但由于元编程代码太复杂,我迷路了

问题 Rails如何知道何时进行SQL更新而不是SQL插入


鉴于我现有的电子邮件地址表,如何更新现有记录?

由于您使用的是非标准id,您需要告诉rails要将该列用作主键,这样它可以评估是否应该插入或更新保存

为此,您需要在模型中添加
self.primary\u key='email\u address\u id'

记住Rails更喜欢约定而不是配置,所以任何时候打破约定都需要告诉Rails


注意:将
电子邮件地址的pkey命名为
电子邮件地址id
,似乎是多余的;通常,FKEY通常使用
resource\u id
的格式,而对于PKEY,您可以定义列名。

谢谢您的回答,但这似乎不是我的问题。这个问题似乎与持久化有关?功能。我会补充更多,因为我知道的更多。我想知道为什么这被否决了,这样我可以在将来改进我的问题。
class EmailAddress < ApplicationRecord
  validates_presence_of :email_address
  validates_format_of :email_address, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :create
  validates_format_of :email_address, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :save
  validates_format_of :email_address, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i, on: :update

  def initialize(email_address_params)
    super(email_address_params)
    confirmation_token()
  end


  # zipcodes can be nil/null in the database but we should never allow a human user to create such a record.
  validates_presence_of :zipcode
  validates_format_of :zipcode, with: /\A\d{5}(-\d{4})?\z/, message: "zipcode should be in the form 12345", on: :create

  def email_activate
    self.email_confirmed = true
    self.confirm_token = nil
    save!(:validate => false)
  end

  private
  def confirmation_token
    if self.confirm_token.blank?
      self.confirm_token = SecureRandom.urlsafe_base64.to_s
    end
  end
end
INSERT INTO "email_addresses" ("email_address_id", "email_address", "zipcode", "confirm_token") VALUES ($1, $2, $3, $4) RETURNING "email_address_id"  [["email_address_id", 2651], ["email_address", "ralphs@dos32.com"], ["zipcode", "80503"], ["confirm_token", "r-UX4zOdOmHC7lO7Ta2pBg"]]
"email_addresses_pkey" PRIMARY KEY, btree (email_address_id)