TimeString
TimeString

Reputation: 1798

How should I add a default value to an attribute in RoR model?

What I want to achieve is the following: When an object is spawned in new action, I want to assign a default value to one attribute in the model, but in edit action, of course I want to use the already entered value. Consider the following simplified model as an example:

class Person < ActiveRecord::Base
  validates :salary, :presence => true
  validates :rank, :presence => true
end

and in the _form.html.erb:

<%= form_for(@person) do |f| %>
    <%= f.text_field :salary %>  # note 1
    <%= f.hidden_field :rank %>
<%= end %>

If this is in the new action (i.e., I'm going to create this person object), I want to set the salary and rank as certain values. (Let's assume the rank may change to a value other than a default value.) But in the edit action, I just want to show previously stored values of an object. What is a good practice to do that?

P.S. I tried to put a value at line note 1 by implementing <%= f.text_field :salary, :value => 100000 %> but the problem toward that is in the edit action, it uses this value, too, which is not desired.

Upvotes: 0

Views: 39

Answers (2)

dp7
dp7

Reputation: 6749

As @Kristjan has suggested, you can have a default value in your db or initialize it within controller.

You can handle this in view as follows:

<%= f.text_field :salary, value: (@person.new_record? ? 100000 : @person.salary) %>

Upvotes: 1

Kristj&#225;n
Kristj&#225;n

Reputation: 18803

There are two ways I'd recommend doing this. The first is to set your defaults in the controller when you initialize your object. That way the view can behave the same way for both new and edit.

class PeopleController < ApplicationController
  def new
    @person = Person.new(salary: 100000)
  end

  def edit
    @person = Person.find(params[:id])
  end
end

Now your view doesn't need to know the default, it just uses the value set on the record in either case.

If it's a stable enough default that you want to set it in the database, Rails will use that value when it initializes the object. Your migration would look like this:

class CreatePeople < ActiveRecord::Migration
  def up
    create_table :people do |t|
      t.integer :salary, default: 100000, null: false
    end
  end
end
Person.new
#=> #<Person:0x000000 salary: 100000>

Upvotes: 1

Related Questions