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