Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem rendering partial in the application layout (Rails)

Here's the call in the application.html.erb file:

<%= render :partial => 'tasks/_new' %>

Here's the partial being rendered (_new.html.erb):

<% form_for @task do |f| -%>
  <%= f.text_field :body %>
  <%= submit_tag "Submit" %>
<% end -%>

Here's the method in the 'tasks' controller:

def new
  @task = Task.new

  respond_to do |format|
    format.html # new.html.erb
    format.xml  { render :xml => @task }
  end
end

Here's the error message I keep getting:

Missing template tasks/__new.erb in view path app/views

And it says the error is in this line:

<%= link_to "tasks", tasks_path %> <%= render :partial => 'tasks/_new' %>

The file is in the right directory. The weird thing is that there's an extra _ in the file name, in the error. When I give in and rename the partial to __new.erb, here's the error I get:

Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

And it says the error is in this line:

<% form_for @task do |f| -%>

I had also tried without the _ in the code, as Petros suggested, but it returns the same error as above, Called id for nil….

What's going on?

like image 913
San Diago Avatar asked Dec 02 '09 02:12

San Diago


2 Answers

You don't need the _ in your code. It should be:

<%= render :partial => 'tasks/new' %>

The first error is because you don't need to put the _ inside the :partial parameter. Rails takes care of that. That's why you get double __ because Rails will put one for you.

The second error is your real problem. The error suggests that @task is nil. This is true because the partial only knows what the container view knows, and your view in that particular moment hasn't called the action from the proper controller. As you (Baby Diego) already found out and indicated in one of your comments below, you needed to create an instance of a Task in your partial. I don't know if there is a more elegant solution, but maybe someone can suggest something better in the future.

Thanks to MattMcKnight for informing us that the partial itself does only know what the container view knows.

like image 76
Petros Avatar answered Sep 21 '22 10:09

Petros


Petros correctly identified the first issue- you don't need the underscore in the partial call. The second thing to know about partials is that they don't call the controller method, they just reference the view. Thus, you need to setup the @task object in every action that uses that partial, or just call Task.new in the partial. When I have a partial in a layout in similar situations, I usually load it with JavaScript so that I can call the action.

like image 33
MattMcKnight Avatar answered Sep 18 '22 10:09

MattMcKnight