如何防止 Rails 检查对象 edited/updated 的唯一约束?

How do I prevent Rails from checking a unique constraint against the object being edited/updated?

我正在使用 Rails 5. 我有一个具有唯一约束的模型

class UserNotification < ActiveRecord::Base

  belongs_to :user
  belongs_to :crypto_currency

  validates_uniqueness_of :buy, scope: [:user_id, :crypto_currency_id]

end

我用这个方法来处理模型的更新

  def update
    @user_notification = UserNotification.new(user_notification_params)
    @user_notification.user = current_user
    respond_to do |format|
      if @user_notification.save
        format.html { redirect_to user_notifications_path, notice: 'Updated successfully.' }
      else
        format.html { render action: "new" }
        @crypto_currencies = CryptoCurrency.where(id: CryptoIndexCurrency.all.pluck(:crypto_currency_id).uniq).order(:name)
        puts "full messages: #{@user_notification.errors.full_messages}"
      end
    end
  end

即使我的数据库中只有一个条目,但当我对现有条目调用上述方法时,我的模型中出现错误,抱怨违反了唯一约束(调用了 else 分支).. .

    Buy has already been taken

如何防止项目针对自身检查唯一约束?也就是说,如果数据库中只有一个条目,那么如果我们正在编辑该条目,则不应抛出唯一约束。

改变

@user_notification = UserNotification.new(user_notification_params)

# I assume that you have id in your params
@user_notification = UserNotification.find(params[:id])
@user_notification.assign_attributes(user_notification_params)

当您执行 UserNotification.new(user_notification_params) 然后尝试 .save 您的记录时,Rails 会生成 INSERT,这就是您遇到唯一性验证错误的原因。

当您调用 assign_attributes 时,您现有的模型将在不保存的情况下填充新值。然后将其 user 更改为 current_user 并调用保存,这将向数据库发送 UPDATE 查询。

当然 UserNotificationid 应该是一个单独的参数。它不应包含在 user_notification_params 中。您只需要它来在数据库中找到所需的记录。