简体   繁体   中英

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 (ie, 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?

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

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>

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) %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM