简体   繁体   中英

Undefined form variable when rendering a partial in rails after an AJAX call

I have been trying for a while to implement a dynamic dependent form using AJAX in rails 4.0. I have a bike model which has_one make and model . It also has_many quotes . The goal is to have the second form's collection field ( model ) populate after the first field make is selected.

The form loads correctly and the AJAX call once the first field is selected is made and returns the appropriate set of data (confirmed via puts in the console). However, I am unable to figure out how to then render the partial appropriately. I am getting the error below. I understand there is no f variable once the partial is rendered via the AJAX call but how do I go about designing the form without the f variable?

ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007f95b0fc2068>:0x007f95b54e2490>):
    1: <%= f.label :name, 'Model' %>
    2: <% if !current_models.blank? %>
    3:  <%= f.collection_select :name, current_models.collect{ |m| [m.name,m.id]}, :id , :name, include_blank: true %>
    4: <% else %>
  app/views/shared/_model_questions_fields.html.erb:1:in `_app_views_shared__model_questions_fields_html_erb__894239665582553972_70140482609500'
  app/controllers/quotes_controller.rb:70:in `update_model_select'

quotes/new.html.erb

<%= form_for @quote do |f| %>
    <%= f.fields_for :bikes do |builder| %>
            <p><%= render 'shared/bike_questions_fields', :f => builder %></p>
    <% end %>
    <%= f.submit "Show Quote", class: "btn btn-large btn-primary" %>
<% end %>

'shared/bike_questions_fields'

<%= f.fields_for :makes do |builder| %>
    <p><%= render 'shared/make_questions_fields', :f => builder %></p>
<% end %>

<%= f.fields_for :models do |builder| %>
    <div id="bikeModels"
        <p><%= render 'shared/model_questions_fields', :f => builder, :current_models => [] %></p>
    </div>
<% end %>

'shared/model_questions_fields'

<%= f.label :name, 'Model' %>
<% if !current_models.blank? %>
    <%= f.collection_select :name, current_models.collect{ |m| [m.name,m.id]}, :id , :name, include_blank: true %>
<% else %>
    <%= f.collection_select :name, [], :id , :name, include_blank: true %>
<% end %>

in quotes controller:

def update_model_select
    models = Model.where(:make_id=>params[:id]).order(:name) unless params[:id].blank?
    render :partial => "shared/model_questions_fields", :locals => { :current_models => models }
end

in quotes.js.coffee:

ready = ->
  jQuery ($) ->

  # when the #make field changes
  $("#quote_bikes_makes_name").change ->

    # make a POST call and replace the content
    make = $("select#quote_bikes_makes_name :selected").val()
    make = "0"  if make is ""
    jQuery.get "/quotes/update_model_select/" + make, (data) ->
      $("#bikeModels").html data

    false


$(document).ready(ready)
$(document).on('page:load', ready)

I solved this by changing 'shared/model_questions_fields' to:

<%= form_for('quote', remote: true) do |f| %>
    <%= f.fields_for :bikes do |g| %>
        <%= g.fields_for :models do |i| %>
            <%= i.label :name, 'Model' %>
            <% if !current_models.blank? %>
                <%= i.collection_select :name, current_models, :id , :name, include_blank: true %>
            <% else %>
                <%= i.collection_select :name, [], :id , :name, include_blank: true %>
            <% end %>
        <% end %>
    <% end %>
<% end %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM