Default values for models in rails

In Rails 5, the attributes API allows specification of default values. The syntax is simple and allows you to change a default without a migration.

# db/schema.rb
create_table :store_listings, force: true do |t|
  t.string :my_string, default: "original default"
end

# app/models/store_listing.rb
class StoreListing < ActiveRecord::Base
  attribute :my_string, :string, default: "new default"
end

Defining defaults in your migration has some disadvantages as well. This will not work when you just call Model.new.

I prefer to write an after_initialize callback, which lets me set default attributes:

class Model < ActiveRecord::Base
  after_initialize :set_defaults, unless: :persisted?
  # The set_defaults will only work if the object is new

  def set_defaults
    self.attribute  ||= 'some value'
    self.bool_field = true if self.bool_field.nil?
  end
end 

Piggy-backing on @w-hile answer — which is a great one, unless you have a bunch of things you want to make "settings" —

I grew sick and tired of polluting my models with a bunch of columns devoted to settings, so I wrote Setsy.

class User < ApplicationRecord

  include ::Setsy::DSL

  # each setting can be a hash, like posts_limit, or just a value
  DEFAULT_SETTINGS = {
    posts_limit: { value: 10 },
    favorite_color: 'blue'
  }.freeze

  setsy :settings, column: :settings_data, defaults: DEFAULT_SETTINGS do |conf|
    conf.reader :posts_limit_and_color do
      "posts limit is #{posts_limit} and color is #{favorite_color}"
    end
  end
end

And you can,

user = User.first
user.settings # {posts_limit: 10, favorite_color: 'blue'}
user.settings.posts_limit # 10
user.settings.posts_limit.default? # true 
user.assign_attributes(settings_data: { posts_limit: 15, favorite_color: 'blue' })
user.settings.posts_limit.default? # false 
user.settings.posts_limit.default # 10