Reputation: 653
Ok, so I am running a Postgres database in Rails 4 and for one of my models Offer the attribute :offer_status
should default to declined. Here is my migration:
def change
create_table :offers do |t|
t.integer :offer_status, default: 0
t.timestamps null: false
end
This :offer_status
attribute refers to an enum in the model like so:
class Offer < ActiveRecord::Base
enum offer_status: [:declined, :accepted]
end
With these two in place I have written a test that will check if a newly created offer will have a default offer_status
of 0.
test "new offers should default to declined" do
@offer2=Offer.new()
assert @offer2.declined?
end
When I call the byebug console mid-test and puts @offer2 I get this:
(byebug) o
<Offer id: nil, offer_status: nil, created_at: nil, updated_at: nil>
(byebug) exit
However, if I do the exact same call o=Offer.new()
in the rails console it returns:
2.2.0 :001 > o=Offer.new
=> #<Offer id: nil, offer_status: 0, created_at: nil, updated_at: nil>
So my question is, why does it work in the console but fail in my tests?
Upvotes: 1
Views: 1036
Reputation: 348
I just had a similar problem. I had to change an already executed migration (to add a default to 0 and to specify null: false
). I executed rake db:rollback STEP=1
and then I've rerun the migration. Everything worked fine, in rails console I was able to see that for every object created the default value for that attribute was 0, but in tests it was always nil
. What it solved it for me was to drop the database (no important data there), recreate it, run the migrations and the tests were executed without failures or errors.
I should mention maybe, that even before I've dropped the database, in the schema.db
for that column the default was already 0 and null: false
. Maybe rake test
uses a different schema, something cached, and not the newest one...
Upvotes: 0
Reputation: 1364
I'm not sure why it does behave differently in the tests, but what you should be aware of, is that the default: 0
is a instruction for your database. It becomes part of the table definition.
Calling new
will create a new ruby object instance, which will have not touched the database until you try to save it. Defining a default just tells the database 'if you don't receive a value for this column, put 0 in it` - But until you send your new Object with save via a SQL query to the DB, this will have absolutely no effect on your object.
Upvotes: 3