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).
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
                        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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With