Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default values for model fields in a Ruby on Rails form

I have a Model which has fields username, data, tags, date, votes. I have form using form_for that creates a new item and puts it into the database. However, as you can guess I want the votes field to equal 0 and the date field to equal the current date when it is placed into the database. How and where would I set/apply these values to the item?

I can get it to work with hidden fields in the form but this comes with obvious issues (someone could set the votes field to a massive number).

like image 823
Callum Rogers Avatar asked Dec 02 '22 03:12

Callum Rogers


2 Answers

Just use a default value; zero, for votes in the db, use the automatic timestamps(created_at) instead of date, and have fields in the form only for the parameters you will set. Don't forget to protect the sensitive attributes.

class CreateModels < ActiveRecord::Migration
  def up
    create_table :models do |t|
      t.string :username
      t.text :data
      t.string :tags
      t.integer :votes, :default => 0

      t.timestamps # this will give you two automatic fields: created_at and updated_at
    end
  end
  …
end

class Model < ActiveRecord::Base
  attr_protected :votes #so that it cannot be set by mass assignment
  …
end
like image 138
edgerunner Avatar answered Dec 04 '22 06:12

edgerunner


I can confirm that DB constraints approach is one of the best. But it is not always possible to be used. Assume there is a single table inheritance and different default value per child model is required. Than I recommend to put this into a model. Let me give an example:

class ChildModel < Model
  after_initialize :set_defaults
  private
  def set_defaults
    self.allowed_votes_per_person = 10 if self.new_record?
  end 
end

By using :after_initialize callback there is no need to create and remember to call :new_default like methods and so on. It sets required default values, but stays unobtrusive from the interface point of view when one calls ChildModel.new

like image 27
rawonstack Avatar answered Dec 04 '22 05:12

rawonstack