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