Ruby on Rails: error when using unobtrusive JavaScript to update partial

248 views Asked by At

I am using Rails 3.2.13, and I'm trying to update a 'summary' partial after creating a 'child' item.

I have a template and template tasks, and what I am trying to do is update the partial on the 'show' view, which is a summary that indicates how many tasks are allocated to the template. I am doing this in the create.js.erb of the template task.

Here are the contents of _template-summary.html.erb:

<div id="template-summary-details">
<table class="table table-striped">
    <tbody>
    <tr>
        <td><span class="fa fa-th-list"></span> No. of tasks</td>
        <td><%= @template.templatetasks.count %></td>
    </tr>
    <tr>
        <td><span class="fa fa-clock-o"></span> Total task days</td>
        <td>                            
            <%= @template.templatetasks.sum(:days) %>
        </td>
    </tr>
    <tr>
        <td><span class="fa fa-check-square-o"></span> No. of checklists</td>
        <td>
            <%= @template.templatetasks.count(:checklist_id) %>
        </td>
    </tr>
    </tbody>
</table>                                
</div>

And here are the contents of create.js.erb:

<% @template = Template.where("id = ?", @templatetask.template_id?) %>

$("#template-summary-details").replaceWith("<%= escape_javascript(render partial:   "templates/template-summary", locals: {template: @template}) %>");

<% if @templatetask.parent_id? %>
$('#templatetasks'+<%= @templatetask.parent_id %>).prepend('<%= j render(@templatetask) %>');
<% else %>
$('#templatetasks').prepend('<%= j render(@templatetask) %>');
<% end %>

The problem is that I am getting the following error:

undefined method `where' for ActionView::Template:Class

I have also tried using find but haven't gotten that to work either.

How else would I pass the @template to the partial during the creation of a template task?

1

There are 1 answers

1
Steve On BEST ANSWER

You first problem is that you have a name clash between the Rails class ActionView::Template and your Template model class. You can work around that by referring to your model class as ::Template (a top-level Ruby class). e.g.

<% @template = ::Template.where("id = ?", @templatetask.template_id).first %>

But that is just a round about way of doing a primary key lookup which is simpler with find:

<% @template = ::Template.find(@templatetask.template_id) %>

Even easier, if you have already set up a belongs_to association from TemplateTask to Template you could just refer to the related object directly:

<% @template = @templatetask.template %>

That would probably get you a bit further but if you want to make your partials more reusable its might be better to avoid having them refer to instance variables (e.g. @template). Instead the partial should refer to a local template variable that you pass into the render method via the locals hash (which you are already doing).