marcamillion
marcamillion

Reputation: 33755

How do I render a partial for a view of a nested resource? - Rails 3.1

This is my route:

scope ":username" do
  resources :feedbacks
end

I am on my home/index.html.erb view and I am trying to do this:

<%= render "feedbacks/form" %>

But this gives me this error:

ActionView::Template::Error (No route matches {:controller=>"feedbacks", :format=>nil}):
    1: <%= form_for(@feedback) do |f| %>
    2:   <% if @feedback.errors.any? %>
    3:     <div id="error_explanation">
    4:       <h2><%= pluralize(@feedback.errors.count, "error") %> prohibited this feedback from being saved:</h2>
  app/views/feedbacks/_form.html.erb:1:in `_app_views_feedbacks__form_html_erb__3181571289116259961_2487495480'
  app/views/home/index.html.erb:18:in `_app_views_home_index_html_erb___397233383548615486_2487321620'

This is my rake routes for feedbacks:

      feedbacks GET    /:username/feedbacks(.:format)          {:action=>"index", :controller=>"feedbacks"}
                POST   /:username/feedbacks(.:format)          {:action=>"create", :controller=>"feedbacks"}
   new_feedback GET    /:username/feedbacks/new(.:format)      {:action=>"new", :controller=>"feedbacks"}
  edit_feedback GET    /:username/feedbacks/:id/edit(.:format) {:action=>"edit", :controller=>"feedbacks"}
       feedback GET    /:username/feedbacks/:id(.:format)      {:action=>"show", :controller=>"feedbacks"}
                PUT    /:username/feedbacks/:id(.:format)      {:action=>"update", :controller=>"feedbacks"}
                DELETE /:username/feedbacks/:id(.:format)      {:action=>"destroy", :controller=>"feedbacks"}

Edit 1

When I pass in the local instance variable @feedback like this: <%= render "feedbacks/form", :local => @feedback %> which is pulling from my home controller, where it is declared like this:

class HomeController < ApplicationController
  def index
        @users = User.all
        @feedback = Feedback.new
  end

end

I still get this error:

Routing Error

No route matches {:controller=>"feedbacks", :format=>nil}

Edit 2

I also have a users resource specified in my routes file, that looks like this:

 resources :users

    scope ":username" do
      resources :feedbacks
    end

Upvotes: 1

Views: 2858

Answers (3)

RobinGower
RobinGower

Reputation: 958

Are you sure you want scope? What about a nested resource as per:

resources :users do
  resources :feedbacks
end

Also, I've had trouble when using controllers with plural names. You might try renaming FeedbacksController to FeedbackController.

Upvotes: 0

Martin Svalin
Martin Svalin

Reputation: 2267

Aren't you forgetting to pass in :username? Your route says scope :username

If I add a route like yours, open up the Rails console, include Rails.application.routes.url_helpers and run feedbacks_path, I get a routing error, but feedbacks_path :username => 'bob' works fine.

> feedbacks_path(:username => 'bob')
=> "/bob/feedbacks"

Upvotes: 1

Brett Bender
Brett Bender

Reputation: 19738

Seems like form_for can't find the correct route, this line suggests you don't have an instance variable @feedback set when trying to render that partial:

(No route matches {:controller=>"feedbacks", :format=>nil})

Notice there is no :id parameter in that hash (which is likely being passed to the router to generate the correct URL to submit the form to).

Do you define a @feedback somewhere in the controller action (preferable) or views you're using? If you think you are, try the following above line 1 of your partial:

logger.info "feedback object: #{@feedback.inspect}"

Edit:

First of all, locals should be passed not as :local => @feedback but as:

:locals => {:variable_name_in_partial => value_for_variable_name}

Second of all, you are trying to access @feedback which is an instance variable accessible to views even if it's not passed explicitly (as long as it's set). So as long as you set it in the HomeController#index method you don't need to pass it to any views locally.

Also, you are not using the correct syntax for rendering partials (wish I had noticed earlier!).

Change the following:

<%= render "feedbacks/form" %>

To this:

<%= render :partial => "feedbacks/form" %>

Upvotes: 2

Related Questions