如何防止Rails检查对正在编辑/更新的对象的唯一约束?

时间:2017-08-30 14:12:43

标签: ruby-on-rails model ruby-on-rails-5 updates unique-constraint

我正在使用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分支)... < / p>

    Buy has already been taken

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

1 个答案:

答案 0 :(得分:0)

更改

@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并调用save,这将向数据库发送UPDATE查询。

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