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?
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.