Reputation: 1050
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?
Upvotes: 6
Views: 8097
Reputation: 3770
If the partial needs to know about a variable in the calling erb file, you can pass it like this:
<%= render partial: "tasks/new", locals: { task: @task } %>
And in file app/views/tasks/_new.html.erb
, refer to the variable like this:
<% form_for task do |f| %>
<%= f.text_field :body %>
<%= submit_tag "Submit" %>
<% end %>
That is, without the @
. (The code a: b
is just a more convenient form of :a => b
.)
I wonder, though, why do you want to use partials in file application.html.erb
? I'm assuming that you mean the Ruby-generated file app/views/layouts/application.html.erb
, which is supposed to be used as a layout file containing elements common to all your application's pages, not for business logic. Perhaps the file you need to call the partial from is app/views/tasks/index.html.erb
?
Upvotes: 1
Reputation: 8992
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.
Upvotes: 9
Reputation: 8290
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.
Upvotes: 4