7

I have gone through tons of the form_for nested resource questions and can't get any of the solutions to work for me. I figured its time to ask a personalized question.

I have two models, jobs and questions, jobs has_many questions and questions belong_to jobs.

I used scaffolding to create the controllers and models then nested the resources in the routes.rb.

root :to => "pages#home"

resources :jobs do
   resources :questions
end

get "pages/home"
get "pages/about"
get "pages/contact"


class Job < ActiveRecord::Base
   has_many :questions
end

class Question < ActiveRecord::Base
   belongs_to :job
end

Right now I am trying to access '/jobs/1/questions/new' and keep getting the

NoMethodError in Questions#new

I started with the error No route matches {:controller=>"questions"} when the code was

<%= form_for(@question) do |f| %>

I know this is wrong, so I started to try other combos and none of them worked.

I've tried

 <%= form_for([@job.questions.build ]) do |f| %>

that

 <%= form_for([@job, @job.questions.build ]) do |f| %>

that

<%= form_for(@job, @question) do |f| %>

Among a bunch of other combinations and that are not working.

Here is a link to my rake routes : git clone https://gist.github.com/1032734

Any help is appreciated and let me know if you need more info, thanks.

Igrabes
  • 244
  • 4
  • 15

2 Answers2

12

I just pass the URL as an extra option:

<%= form_for(@question, :url => job_questions_path(@job)) do %>

EDIT:

Also try:

form_for([@job, @question])
K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
d11wtq
  • 34,788
  • 19
  • 120
  • 195
  • The first option worked, thanks! - what does passing the url do that fixes this? Also, the job_id for the question isn't updating in the DB - any idea how to fix that? FYI: the edit returned this error: No route matches {:controller=>"questions"} – Igrabes Jun 18 '11 at 05:18
  • When you don't pass the `:url` option, Rails tries to work it out by itself. It doesn't know that `Question` is always a sub-resource of `Job`, because it doesn't always have to be. With regards to the `job_id` not being updated, if you're using mass-assignment, it's probably ignoring it. Call `question.job = new_job` separately. I can't see your code though. – d11wtq Jun 18 '11 at 06:14
  • Hey @d11wtq, i'm not entirely sure what you mean by Call question.job = new_job - where does that go? Here is my repo [link(https://github.com/igrabes/InterQ) , if that helps. – Igrabes Jun 18 '11 at 12:39
  • You'll have to either post a new question with the new problem, or update your existing question, as I'm not clear on what the issue is. It sounded like you were trying to do something like `question.update_attributes({:job_id => 1})`, which wouldn't work. But it's probably best you describe the problem more in detail. – d11wtq Jun 18 '11 at 13:14
  • Just looked at your code. You're never passing the `job_id` to `Question`, so it will never get a `job_id`. Try `@job.questions.new(params[:question])`. That should make sure it has the correct reference. You should really load the `Job` anyway, just to make sure the `job_id` actually exists. `@job = Job.find(params[:id])`, then `@question = @job.questions.new(params[:question])`. – d11wtq Jun 18 '11 at 13:18
  • Or is it `build`, in place of `new`, sorry? :) I forget, I don't use ActiveRecord. But the principle still stands. – d11wtq Jun 18 '11 at 13:19
  • @d11wtq Thanks, build worked! I think I am getting the hang of it. – Igrabes Jun 21 '11 at 04:32
2

This is how I solved mine :)

In your questions/_form.html.erb

<%= form_for [@job, @question] do %>

For this to work, you need the job's id. You'll pass it as follows: In the questions_controller.rb

def new
  @job = Job.find(params[job_id])
  @question = @job.questions.build
end

Build(.build) is similar to using new(.new) in the code above, with differences only in older versions of rails; rails 2 down.

Now for the create action (still in questions_controller.rb)

def create
  @job = Job.find(params[:job_id])
  @question = @job.questions.build(question_params)
end

If you only use these, the job_id and user_id field in the question model will be empty. To add the ids, do this: In your questions_controller.rb add job_id to job_params like so:

def question_params
  params.require(:question).permit(:ahaa, :ohoo, :job_id)
end

Then to pass the user's id (if you are using Devise), do:

def create
  @job = Job.find(params[:job_id])
  @question = @job.questions.build(question_params)
  @question.user_id = current_user.id
end
Kaka Ruto
  • 4,581
  • 1
  • 31
  • 39