【问题标题】:Rails Active Record cancel (save or create) within before_create callback without raising exceptionRails Active Record 在 before_create 回调中取消(保存或创建)而不引发异常
【发布时间】:2016-12-02 14:41:33
【问题描述】:

其实我想测试一个模型回调。

system_details.rb(模型)

class SystemDetail < ActiveRecord::Base
  belongs_to :user
  attr_accessible :user_agent

  before_create :prevent_if_same    

  def agent
    Browser.new(ua: user_agent, accept_language: 'en-us')
  end

  def prevent_if_same
    rec = user.system_details.order('updated_at desc').first
    return true unless rec
    if rec.user_agent == user_agent
      rec.touch
      return false
    end
  end
end

prevent_if_same 方法工作正常并且按预期工作,但是当它返回 false 时会引发异常 ActiveRecord::RecordNotSaved,并且异常会破坏 rspec test。我想要的是,它应该默默地取消保存而不引发异常。

system_detail_spec.rb (rspec)

require 'rails_helper'

RSpec.describe SystemDetail, :type => :model do      

  context '#agent' do
    it 'Checks browser instance' do
      expect(SystemDetail.new.agent).to be_an_instance_of(Browser)
    end
  end

  context '#callback' do    
    it 'Ensure not creating consecutive duplicate records' do
      user = create :end_user
      system_detail = create :system_detail, :similar_agent, user_id: user.id
      updated_at  = system_detail.updated_at
      system_detail2 = create :system_detail, :similar_agent, user_id: user.id
      system_detail.reload

      expect(system_detail2.id).to be_nil
      expect(system_detail.updated_at).to be > updated_at
    end
  end        
end

第二次测试#callback 因异常而失败。

失败:

1) SystemDetail#callback 确保不创建重复记录 失败/错误:system_detail2 = 创建:system_detail,:similar_agent,user_id:user.id ActiveRecord::RecordNotSaved: ActiveRecord::RecordNotSaved

有什么方法可以在不引发异常的情况下静默取消保存?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord rspec callback


    【解决方案1】:

    我认为在这种情况下使用validate :prevent_if_same 更好,因为基本上你的方法是一种验证规则。它也会阻止默默地创建。如果您想通知用户创建不成功,您可以随时添加错误

    【讨论】:

    • 嗨@dziamber,感谢您的回答。这里我不想通知用户创建不成功,只是想如果连续上一条记录相同,就更新上一条记录。
    • 所以我认为使用validate :prevent_if_same 会为您完成工作
    • validate :prevent_if_same的情况下我必须强制添加一个错误取消save/create,否则记录被保存。添加错误将引发带有已定义错误消息的异常,这是我不想要的。我只想优雅地跳过保存,没有任何例外。
    • 调用save!会报错,调用save不会报错
    • 我是调用create不保存,看测试用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多