5

I'm making an app with the following attributes, and I'm working on a creating a single form to be able to save a goal, a goal's tasks, a goal's milestones, and a milestone's tasks.

#app/models/goal.rb
  has_many :tasks, :as => :achievement
  has_many :milestones
  accepts_nested_attributes_for :tasks
  accepts_nested_attributes_for :milestones

#app/models/milestone.rb
  belongs_to :goal
  has_many :tasks, :as => :achievement

#app/models/task.rb
  belongs_to :achievement, :polymorphic => true

Whenever I save a goal with it's attributes, it seems the task models are getting confused as to what achievement_type they belong to, resulting in every milestone task just being listed as a goal task. My form, partials, and controller code are below.

form:

<%= nested_form_for @goal do |f| %>

  <%= render 'shared/error_messages', :object => f.object %>
  <%= render 'shared/goal_fields', :f => f %>

  <%= f.fields_for :milestones do |ff| %>
    <%= render 'shared/milestone_fields', :f => ff %>
  <% end %> 

  <%= f.fields_for :tasks do |ff| %>
    <%= render 'shared/task_fields', :f => ff %>
  <% end %>

  <%= f.link_to_add "Add Milestone", :milestones %>
  <%= f.link_to_add "Add Task", :tasks %>

  <%= f.submit %>

<% end %>

milestone_fields partial:

  <%= f.label :content, "Milestone" %>
  <%= f.text_field :content %>

  <%= f.fields_for :tasks do |ff| %>
    <%= render 'shared/task_fields', :f => ff %>
  <% end %>

  <%= f.link_to_remove "Remove milestone" %>
  <%= f.link_to_add "Add Milestone Task", :tasks %>

task_fields partial:

  <%= f.label :content, "Task" %>
  <%= f.text_field :content %>
  <%= f.link_to_remove "Remove Task" %>

goal controller:

def new
  @goal = current_user.goals.new
end

def create
  @user = current_user
  @goal = @user.goals.build(params[:goal])
  if @goal.save
    flash[:success] = "Goal created!"
    redirect_to goals_path 
  else
    render 'new'
  end 
end 

I tried adding @goal.milestones.build and @goal.tasks.build next to the f.fields_for code, which seems to have fixed it, but leads to other problems such as a blank edit form(no data is pre-populated) and the milestone and task fields showing up immediately instead of clicking a link to bring up a blank field. If you can't solve it, are there any sites where I can pay other coders to help solve a small problem like this? I'm desperate at this point.

Grant David Bachman
  • 2,158
  • 3
  • 21
  • 32

1 Answers1

2

Your Milestone model needs the following line to be able to accept tasks_attributes:

# app/models/milestone.rb
accepts_nested_attributes_for :tasks

Everything else in the models look good. As for the fields_for form helper, passing build will create a new instance of the object specified, which will result in the blank edit form you describe. Try removing these builds if nested_form_for is going to handle building and appending these new form fields.

I recreated your environment, and when I post my form, I get the following params hash in the server log:

{"goal"=>{"milestones_attributes"=>{"0"=>{"content"=>"foo", "tasks_attributes"=>{"0"=>{"content"=>"bar"}}}}, "tasks_attributes"=>{"0"=>{"content"=>"baz"}}}}

This created two Task records, one of achievement_type 'Goal', and the other of achievement_type 'Milestone'

As for paying someone to do this work, http://www.rent-acoder.com/ is a website I have heard people say they have accepted work from in the past.I can't speak for the quality of the code, but you can post your work and see what bites you get.

Ben Simpson
  • 4,009
  • 1
  • 18
  • 10
  • Thanks Ben, I actually already had the accepts_nested_attributes_for line, just forgot to copy it in. Aside from that, I'm just not getting the output you are. If you'd like to take some time to help me solve this problem, I can push my (obviously not working) code to github. I could compensate you if needed. My email is grantbachman@gmail.com. I've just had it with this problem and I'm ready to quit haha. – Grant David Bachman Jul 13 '11 at 02:58
  • 2
    Grant, I think you are almost there on this code. Lets keep the troubleshooting in Stack Overflow, so that other people can see the solution. Try stripping the issue down to the essentials, then layering additional code on top of it once the essentials work. Try using "form_for" and get that working before introducing "nested_form_for". What does your params hash look like when you submit the form? – Ben Simpson Jul 13 '11 at 13:51
  • 1
    I stripped it down into a regular form_for like you suggested and built some static fields from the 'new' action, and it works perfectly fine now. The problem arises when I try to add blank fields using the link_to_add method of the nested_form_for. I'm guessing this is a problem with using gems like nested_form_for, you don't really know how they work so it's tough to troubleshoot. I'm just going to find some tutorials online and see if I can write my own function that fixes this problem. If you have any other suggestions, though, I'm all ears. Thanks Ben. – Grant David Bachman Jul 13 '11 at 16:09
  • I'd suggest, like Ben said, start at the basics. I'd go a step further, and create a new app and start again with just those components you're focusing on. Strip out the unnecessary relationships and models etc. You're clearly new at this (not a zing) and so learning this way is great! You're gonna be much better off when you figure out what you're doing wrong. Start as simple as possible, write tests to keep you on track along the way, and check out http://railscasts.com/episodes/196-nested-model-form-part-1. That might give you just the kick you need. Also, try taking a break from it! :) – Volte Mar 09 '13 at 19:41