1

I'm working on a project where there are tasks that make up a scavenger hunt. When a user creates a new hunt, I'd like the hunts/show.html.erb file to show the hunt as well as the tasks associated with that hunt. But the models are giving me trouble. I've got the hunt model setup to that it accepts nested attributes for the tasks model. So when the user creates a new hunt, she also creates three tasks automatically. I can get the new hunt to save, but I can't get those new tasks to save. Here are my models.

What's missing? Do I need an "attr accessible" statement in the HunTasks.rb file?

class Hunt < ActiveRecord::Base

  has_many :hunt_tasks
  has_many :tasks, :through => :hunt_tasks
  accepts_nested_attributes_for :tasks, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
  attr_accessible :name
  validates :name,  :presence => true,
                    :length   => { :maximum => 50 } ,
                    :uniqueness => { :case_sensitive => false }

end


class Task < ActiveRecord::Base

  has_many :hunt_tasks
  has_many :hunts, :through => :hunt_tasks
  attr_accessible :name    
  validates :name,  :presence => true,
                    :length   => { :maximum => 50 } ,
                    :uniqueness => { :case_sensitive => false }   
end


class HuntTask < ActiveRecord::Base     
  belongs_to :hunt # the id for the association is in this table
  belongs_to :task
end

Here's what my Hunt controller looks like:

class HuntsController < ApplicationController

  def index
     @title = "All Hunts"
     @hunts = Hunt.paginate(:page => params[:page])
  end

  def show
    @hunt = Hunt.find(params[:id])
    @title = @hunt.name 
    @tasks = @hunt.tasks.paginate(:page => params[:page])
  end

  def new
    if current_user?(nil) then    
      redirect_to signin_path
    else
      @hunt = Hunt.new
      @title = "New Hunt"
      3.times do
        hunt =  @hunt.tasks.build   
      end
    end
  end

  def create
    @hunt = Hunt.new(params[:hunt])
    if @hunt.save
      flash[:success] = "Hunt created!"
      redirect_to hunts_path
    else
      @title = "New Hunt"
      render 'new'     
    end
  end
....
end
tereško
  • 58,060
  • 25
  • 98
  • 150
Ben Downey
  • 2,575
  • 4
  • 37
  • 57
  • hey again Ben ;) just checking, you run the migration for HuntTasks, right? Also please show the relevant controller code, thx, Michael. – Michael Durrant Mar 31 '12 at 22:03
  • 1
    btw this railscast is pretty well know for this: http://railscasts.com/episodes/196-nested-model-form-part-1 – Michael Durrant Mar 31 '12 at 22:06
  • Hello! Great to see you again! To answer your question, yes, I've run the migration. Also, I've just posted the hunt controller in the main section of my post. And yes, I'm working off Railscast 196, but Mr. Bates makes it look really easy, whereas I'm finding it to be a long hard slog. – Ben Downey Mar 31 '12 at 22:16

1 Answers1

0

The major difference between your example and the railscast is that you are doing many-to-many instead of one to many (I think his was Survey had many Questions). Based on what you described, I wonder if the HuntTask model is necessary. Are the tasks for one hunt ever going to be resused in another hunt? Assuming they are, then looks like your answer is here:

Rails nested form with has_many :through, how to edit attributes of join model?

You'll have to modify your new action in the controller to do this:

hunt =  @hunt.hunt_tasks.build.build_task

Then, you'll need to change your Hunt model to include:

accepts_nested_attributes_for :hunt_tasks

And modify your HuntTask model to include:

accepts_nested_attribues_for :hunt
Community
  • 1
  • 1
Adam
  • 3,148
  • 19
  • 20
  • I've been playing with this setup, but without much success. I always end up with an association error `ArgumentError in HuntsController#new No association found for name `hunt_tasks'.` – Ben Downey Apr 01 '12 at 16:06
  • Just to confirm: the 'accepts_nested_attributes_for :hunt_tasks' line was placed after both 'has_many :hunt_tasks' and 'has_many :tasks, through...' in your Hunt model? – Adam Apr 01 '12 at 20:43
  • 1
    Hmmm, well, from looking at the code [here](https://github.com/rails/rails/blob/master/activerecord/lib/active_record/nested_attributes.rb) it looks like that should only happen if has_many :hunt_tasks hadn't been declared prior to accepts_nested_attributes_for :hunt_tasks in Hunt. I'm not sure where else to point you. Perhaps the database hasn't been set up in a way that corresponds to the models? That is, there isn't a 'hunt_tasks' table that references both 'hunts' and 'tasks'? – Adam Apr 02 '12 at 15:48
  • I double checked, just in case, but here the migration I wrote and ran. ` create_table "hunt_tasks", :force => true do |t| t.integer "hunt_id" t.integer "task_id" t.datetime "created_at" t.datetime "updated_at" end` – Ben Downey Apr 02 '12 at 20:39
  • I'm having a similar problem faced above. – Mittenchops Aug 04 '12 at 01:46