Reputation: 13
I have some code where I create ActiveRecord objects as constants in my model like so:
class OrderStage < ActiveRecord::Base
validates :name, presence: true, uniqueness: true
DISPATCHED = find_or_create_by(name: 'Dispatched')
end
Each Order has an OrderStage:
class Order < ActiveRecord::Base
belongs_to :order_stage
end
Now this seems to work fine throughout the site, and in my integration tests. However it is breaking in my unit test. The following test
it 'lists all order stages' do
# using FactoryGirl
create(:order, order_stage: OrderStage::DISPATCHED)
expect(Order.all.map(&:order_stage)).to eq [OrderStage::DISPATCHED]
end
passes fine when I run it individually, or when I run just order_spec.rb
. But when I run the whole test suite, or even just spec/models
I get this error:
Failure/Error: expect(Order.all.map(&:order_stage)).to eq [OrderStage::DISPATCHED]
expected: [#<OrderStage id: 1, name: "Dispatched">]
got: [nil]
That error goes away if I write my test like so:
it 'lists all order stages' do
order_stage = OrderStage.find_or_create_by(name: 'Dispatched')
create(:order, order_stage: order_stage)
expect(Order.all.map(&:order_stage)).to eq [order_stage]
end
So it must be something to do with creating the ActiveRecord object in the constant, it this a bad thing to do?
Upvotes: 1
Views: 91
Reputation: 960
You should use class method.
attr_accessible :name
def self.dispatched
@dispatched ||= find_or_create_by_name('Dispatched')
end
private
def self.reset!
@dispatched = nil
end
Upvotes: 1