Ruby on rails 应该在回调之前

Ruby on rails 应该在回调之前,ruby-on-rails,rspec,ruby-on-rails-4,shoulda,Ruby On Rails,Rspec,Ruby On Rails 4,Shoulda,我有一个简单的模型: class Category < ActiveRecord::Base belongs_to :board validates :name, presence: true, uniqueness: {scope: :board_id} validates :board, presence: true validates :display_order, presence: true, uniqueness: {scope: :board_id} b

我有一个简单的模型:

class Category < ActiveRecord::Base
  belongs_to :board
  validates :name, presence: true, uniqueness: {scope: :board_id}
  validates :board, presence: true
  validates :display_order, presence: true, uniqueness: {scope: :board_id}

  before_save :set_display_order

  private

  def set_display_order
    last = self.board.categories.order("display_order DESC").last
    self.display_order = last.display_order + 100 if last
  end
end
带有错误(此if用于私有方法中的行
last=…
):

其他应力测试工作正常:

  it { should validate_presence_of(:name) }
  it { should validate_presence_of(:board) }
  it { should belong_to :board }

知道这里有什么问题吗?我试图将保存之前的
更改为验证之前的
,但仍然是一样的。

因为应该在DB中创建记录。Gem创建记录跳过验证

确保如果给定属性不唯一,则模型无效。它使用第一条现有记录,如果数据库中不存在记录,则创建一条新记录。它只是使用“:validate=>false”绕过验证,因此如果存在“notnull”约束,它可能会失败。在这种情况下,您必须在调用“验证唯一性”之前创建一条记录。

在您的案例中,创建的
category
为空意味着
category.board#=>nil
,您从nil调用方法
categories


您应该自己为唯一性测试创建一个记录。

解决shoulda_matchers和AR回调限制的一种方法是重新定义shoulda matchers使用的测试主题

例如:

# category_spec.rb

# assuming you're using factorygirl and have this setup correctly
let(:board) { FactoryGirl.create(:board, :with_many_categories) }
subject { FactoryGirl.build(:category, board: board) }

# your shoulda matcher validations here
  it { should validate_presence_of(:name) }
  it { should validate_presence_of(:board) }
  it { should belong_to :board }
# category_spec.rb

# assuming you're using factorygirl and have this setup correctly
let(:board) { FactoryGirl.create(:board, :with_many_categories) }
subject { FactoryGirl.build(:category, board: board) }

# your shoulda matcher validations here