Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default values for models in rails

Is it better to set default value in migration or in callback? It's difficult to delete (or set another) default value in migration, but in model it one more piece of code

like image 703
Denis Papushaev Avatar asked Apr 11 '15 07:04

Denis Papushaev


3 Answers

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 
like image 89
Sharvy Ahmed Avatar answered Oct 22 '22 19:10

Sharvy Ahmed


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
like image 29
w_hile Avatar answered Oct 22 '22 19:10

w_hile


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 
like image 3
Josh Brody Avatar answered Oct 22 '22 21:10

Josh Brody