How to fill in the table in the luminaire rails?
Short summary: I have a Rails application that is a personal to-do list / to-do list. Basically, you can enter and manage your to-do list.
My question: When a user creates a new account, I want to populate my checklist with 20-30 default items. I know I can say:
wash_the_car = ChecklistItem.new
wash_the_car.name = 'Wash and wax the Ford F650.'
wash_the_car.user = @new_user
wash_the_car.save!
...repeat 20 times...
However, I have 20 lines of ChecklistItem to fill, so this will be 60 lines of very wet code (not DRY). There must be a better way.
So, I want to use the ChecklistItems semantic table from the YAML file when creating an account. The YAML file can contain all my ChecklistItem objects. When a new user is created - bam! - there are preset items in the list.
How to do it?
Thanks!
(PS: For those of you wondering WHY I am doing this: I am doing a login to login to my web design company. I have a set of 20 steps (first meeting, design, checkout, test, etc.) that I review every web client. These 20 steps are 20 checklist items that I want to complete for each new client. However, when everyone starts with the same 20 items, I usually customize the steps that I will use based on project (and thus my implementation of the vanilla to-do list and desire to fill in the lines programmatically) If you have any questions, I can explain further.
a source to share
I agree with other respondents suggesting that you just do it in code. But it doesn't have to be as detailed as suggested. This is already one liner if you want it to be:
@new_user.checklist_items.create! :name => 'Wash and wax the Ford F650.'
Throw this into a loop of elements that you read from a file, or store in your class, or wherever you like:
class ChecklistItem < AR::Base
DEFAULTS = ['do one thing', 'do another']
...
end
class User < AR::Base
after_create :create_default_checklist_items
protected
def create_default_checklist_items
ChecklistItem::DEFAULTS.each do |x|
@new_user.checklist_items.create! :name => x
end
end
end
or if your objects are increasing in complexity, replace the array of strings with an array of hashes ...
# ChecklistItem...
DEFAULTS = [
{ :name => 'do one thing', :other_thing => 'asdf' },
{ :name => 'do another', :other_thing => 'jkl' },
]
# User.rb in after_create hook:
ChecklistItem::DEFAULTS.each do |x|
@new_user.checklist_items.create! x
end
But I don't really suggest that you select all the defaults in the constant inside ChecklistItem
. I just described it so that you can see the structure of the Ruby object. Instead, throw them into the YAML file you read once and the cache:
class ChecklistItem < AR::Base
def self.defaults
@@defaults ||= YAML.read ...
end
end
Or, if you want Wand admins to be able to manage the defaults on the fly, put them in the database:
class ChecklistItem < AR::Base
named_scope :defaults, :conditions => { :is_default => true }
end
# User.rb in after_create hook:
ChecklistItem.defaults.each do |x|
@new_user.checklist_items.create! :name => x.name
end
Lots of options.
a source to share
A Rails Fixture is used to populate test data for unit tests; Don't assume this is meant to be used in the scenario you mentioned.
I would say just extract the new method add_checklist_item
and be done with it.
def on_user_create
add_checklist_item 'Wash and wax the Ford F650.', @user
# 19 more invocations to go
end
If you want more flexibility
def on_user_create( new_user_template_filename )
#read each line from file and call add_checklist_item
end
The file can be a simple text file with each line corresponding to a description of the task, for example "Wash and wax the Ford F650". It should be pretty easy to write in Ruby,
a source to share