Search code examples
ruby-on-railsrubynullminitestbyebug

Rails Testing Default Value in database fails


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?


Solution

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