michaelward82
michaelward82

Reputation: 4736

Rails: Creating default records for has_many relationship

I have a rails 3.2 app for a budget planner.

My model features a user, a user has one budget, and each budget has many budget_items. When a user is created, a budget is created for them.

When the user accesses their budget, I insert a blank budget_item if they have none. However, what I would like to do is prepopulate each budget with a set of default budget items with estimated costs. This can be done either on creation of the budget, or if the user accesses a blank budget.

I would like as clean an implementation as possible, as I'm trying to do things the 'right way' in Rails (not quite there yet if you see any unusual code :)

My code can be seen here: https://github.com/michaelward82/WeddingPlanner

Well though out answers will be considered better than quick answers. I will give a reasonable amount of time before awarding a correct answer.


Edit:

I have succedded in achieving the creating of default records by changing my BudgetsController in the following manner:

class BudgetsController < ApplicationController
  def show
    if current_user
      @budget = current_user.budget
      if @budget.budget_items.empty?
        set_default_budget_items @budget
      end
    else
      redirect_to log_in_path
    end
  end

  def update
    @budget = current_user.budget
    if @budget.update_attributes(params[:budget])
      redirect_to budget_path, :flash => { :success => "Budget changes saved" }
    else
      redirect_to budget_path, :flash => { :error => "Budget changes were not saved" }
    end
  end

  private

  def set_default_budget_items(budget)
    default_budget_items = [
      { "description"=>"Insurance", "estimated_cost"=>"110", "actual_cost"=>"0", "position"=>"1"},
      { "description"=>"The Service", "estimated_cost"=>"520", "actual_cost"=>"0", "position"=>"2"},
      { "description"=>"Reception (venue, food & drinks)", "estimated_cost"=>"4000",  "actual_cost"=>"0", "position"=>"3"}
    ]

    default_budget_items.each {|b| @budget.budget_items.new(b) }
  end
end

Is this the best way? I'm happy to go with this, but if there is a cleaner way to organise this then I'd be happy to know. There are sgnificantly more default items than seen above, so I doubt my controller is the place for this data to live.

Upvotes: 2

Views: 848

Answers (1)

Stu
Stu

Reputation: 1567

I think that you're making a heavy controller and this should probably be moved to the model. You want to keep your controllers skinny where possible. There's plenty of articles on this google 'rails skinny controllers'.

http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model

I would use a callback (probably after_create), depending on what exactly you plan for the rest of the application.

Upvotes: 3

Related Questions