user7010020
user7010020

Reputation:

ActionView::Template::Error (undefined local variable or method...or no error

I wanted to use create action with ajax on 'index' page. I found some similiar problems here on SO, tried to use it, but no help for me so far. HTML works fine, only JS is a problem.

walls_controller:

def items
  @item = Item.new
  @items = current_user.items
  find_items
  @ads = @items_ads
end

def create
  @items = current_user.items
  find_items
  #@items_ads via find_items method
  @ads = @items_ads  
  @item = current_user.items.build item_params
  current_user.save
  respond_to do |format|
    format.html { redirect_to :back }
    format.js
  end
end

items.html.erb:

<div id="items1">
  <div class="row">
    <div class="col-md-3">
      <h3>Wall of user <%= current_user.name %></h3>
      <div>
        <%= render 'item_form', item: @item %>
      </div>
      Currently you are looking for these items:
      <div>
        <%= render 'items_list', items: @items %>
      </div>
    </div>
    <div>
      <%= render 'ads/ads_list', ads: @ads %>
    </div>
  </div>
</div>

_item_form.html.erb:

<%= form_for(item, url: wall_items_path, remote: true) do |f| %>
...

First I had error:

ActionView::Template::Error (undefined local variable or method `items' for #<#<Class:...

then I changed create.js.erb from

$("#items1").html("<%= render 'items_list', locals: {items: @items} %>");
$("#items1").html("<%= render 'ads_list', locals: {ads: @ads} %> ");

to

$("#items1").html("<%= render 'items_list', items: @items %>");
$("#items1").html("<%= render 'ads/ads_list', ads: @ads %>");

and now it doesn't show me any error, but no visible change when trying JS on browser. Thanks for help.

Upvotes: 1

Views: 8014

Answers (1)

Carlos Ramirez III
Carlos Ramirez III

Reputation: 7434

Rendering Partials

You can render a partial with local data in two ways:

Option 1

The shortcut version

<%= render "my_partial", local_var_1: some_var, local_var_2: another_var %>

The shortcut version takes the partial name as the first argument and a hash of local variables as the second parameter.

Option 2

The long form version

This form takes only a single argument in the form of a Hash with all the options.

Don't mix-and-match forms

Doing the following will yield unexpected results

<%= render "my_partial", locals: { local_var_1: some_var, local_var_2: another_var } %>

Technically here you are using the shortcut version (Option 1), rendering a partial named "my_partial" with a single local variable called locals.

You would expect to be able to use local_var_1 and local_var_2 within the partial, however you actually only get a single local variable called locals.


Rendering Partials in an SJR template

escape_javascript GOTCHA

In a server-generated JavaScript template (SJR), you must remember to use escape_javascript whenever you are rendering content which contains HTML.

$("#my-selector").html("<%= escape_javascript render('my_partial') %>");

Regardless of how you choose to render the partial (i.e. either Option 1 or Option 2 above), you must remember to wrap it in an escape_javascript (or its alias j) call.

Helpful Resources

Upvotes: 2

Related Questions