简体   繁体   中英

Ruby on Rails - error when re-loading partial on click event

I am trying to reload a partial used in a form in order to update the time that is displayed in a 'stop time' field that is in a view.

I am getting the error when I try to reload the partial on a click event.

I have reviewed similar questions such as: Rails refresh partial , on the SO site and I was unable to resolve the error when I tried to apply the answers from the other questions.

Any comments or suggestions to help resolve this error is appreciated.

Thanks in advance for your help.

My Application environment is:

  • Rails version 4.2.7.1
  • Ruby version 2.3.4-p301 (x86_64-linux)
  • RubyGems version 2.6.11
  • JavaScript Runtime Node.js (V8)

I have defined the 'update_stoptime' action in the controller as:

class UsercatsController < ApplicationController  
  #######################################
  # define action to update stop time
  #######################################
  def update_stoptime

    @ustoptime = Time.current.strftime("%I:%M %p")

    p 'print @ustoptime time value (Time.current) below for update_stoptime action in Usercats controller'
    p @ustoptime

    respond_to do |format|
        format.js 
    end

  end

# GET /usercats/new
  def new

     p 'current user ID for NEW action is:'
     p current_user.id

     @usercat = current_user.usercats.build

     @ustoptime = Time.current.strftime("%I:%M %p")

     p 'print @ustoptime time value below for new action in controller(Time.current)'
     p @ustoptime

  end

end

The partial is saved under the "../views/stoptimes" folder as:

# _stoptime.html.erb

<div id='update_stoptime'>
   <%= f.input :stoptime, required: true, input_html: {value: @ustoptime}, :label => "Stop Time:", :ampm => true %>
</div>

The partial is rendered from a file that is saved under the ../views/usercats folder as:

# _form.html.erb

<%= simple_form_for(@usercat) do |f| %>
    <%= f.error_notification %>

  <div class="form-inputs">
    <%= render 'stoptimes/stoptime', f: f %>
  </div>


  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

Under the ../views/usercats folder I am using the following JS Coffee file to reload the partial on the click event:

# app/views/usercats/update_stoptime.js.coffee

$("#update_stoptime").load("<%= j render partial: 'stoptimes/stoptime',  locals: { f: f } %>");

I updated the routes.rb file with the line below:

get 'usercats/update_stoptime', as: 'update_stoptime'

And under the "../app/assets/javascripts/" folder I have created a JS Coffee file with an AJAX call:

# stoptime.js.coffee

$ ->
  $(document).on 'click', '#update_stoptime', (evt) ->
      $.ajax 'update_stoptime',
      type: 'GET'
     dataType: 'script'
     error: (jqXHR, textStatus, errorThrown) ->
     console.log("AJAX Error: #{textStatus}")
     success: (data, textStatus, jqXHR) ->     
     console.log("script loaded OK!")

I have listed the error below:

Started GET "/usercats/update_stoptime?_=1539021470900" for 104.194.218.93 at 2018-10-08 17:58:58 +0000

Processing by UsercatsController#update_stoptime as JS
  Parameters: {"_"=>"1539021470900"}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 1]]

"print @ustoptime time value (Time.current) below for update_stoptime action in controller"
"01:58 PM"
  Rendered usercats/update_stoptime.js.coffee (45.7ms)
Completed 500 Internal Server Error in 53ms (ActiveRecord: 0.2ms)

ActionView::Template::Error (undefined local variable or method `f' for #<#<Class:0x007f736a255078>:0x007f7369f05698>):
  1: # app/views/usercats/update_stoptime.js.coffee
  2: $("#update_stoptime").load("<%= j render partial: 'stoptimes/stoptime',  locals: { f: f } %>");

app/views/usercats/update_stoptime.js.coffee:2:in '_app_views_usercats_update_stoptime_js_coffee___2918126501527502339_70066841111240'
app/controllers/usercats_controller.rb:32:in 'update_stoptime'

##############################################################

Update, I have added information below that was used to resolve the error when reloading partial on click event.

##############################################################

I decided to store stop time as a character value based on the answer from @IlyaKonyukhov.

First I generated the migration below to add a character stop time variable to my model.

rails g migration add_cstoptime_to_usercat cstoptime:string

Next I updated the AJAX call in the JS Coffee file under the "../app/assets/javascripts/" folder to pass an instance variable from the controller to the view.

#stoptime.js.coffee
$ ->
   $(document).on 'click', '#update_stoptime', (evt) ->
     $.ajax 'update_stoptime',
     type: 'GET'
     dataType: 'script'
     data: {
             cstoptime: @ustoptime
           } 
    error: (jqXHR, textStatus, errorThrown) ->
      console.log("AJAX Error: #{textStatus}")
    success: (data, textStatus, jqXHR) ->
      console.log("script loaded OK!")

Next I updated the 'new' and 'update_stoptime' actions in the controller to output a string value for stop time.

class UsercatsController < ApplicationController  
  #######################################
  # define action to update stop time
  #######################################
  def update_stoptime

    @ustoptime = Time.current.strftime("%I:%M %p").to_s

    p 'print @ustoptime time value (Time.current) below for update_stoptime action in Usercats controller'
    p @ustoptime

    respond_to do |format|
        format.js 
    end

  end

# GET /usercats/new
  def new

     p 'current user ID for NEW action is:'
     p current_user.id

     @usercat = current_user.usercats.build

     @ustoptime = Time.current.strftime("%I:%M %p").to_s

     p 'print @ustoptime time value below for new action in controller(Time.current)'
     p @ustoptime

  end

end

Next I updated the partial that is saved under the "../views/stoptimes" folder:

#app/views/stoptimes/_stoptime.html.erb
<input value="<%= @ustoptime %></input>

Next I updated the JS Coffee file to reload the stop time value on the click event:

# app/views/usercats/update_stoptime.js.coffee
$("#update_stoptime").val("<%= @ustoptime %>");

Next I updated the form that is saved under the ../views/usercats folder:

# _form.html.erb

<%= simple_form_for(@usercat) do |f| %>
    <%= f.error_notification %>

 <%= f.input :cstoptime, :label => "Record stop time:",  
           input_html: {id: 'update_stoptime', :style => "width:110px", value:  @ustoptime, class: "form-control"} %>


  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

The value for stop time started automatically updating on the click event without any errors after I made the revisions/updates that I have listed above.

Thank you @IlyaKonyukhov for your comments and suggestions.

try to change this to:

$("#update_stoptime").html("<%= escape_javascript(render partial: 'stoptimes/stoptime', locals: { f: f }) %>");

Well, the error message undefined local variable or method `f' clearly indicates what the problem is.

In response to a AJAX-request of 'usercats/update_stoptime' the server processes this template:

# app/views/usercats/update_stoptime.js.coffee
$("#update_stoptime").load("<%= j render partial: 'stoptimes/stoptime',  locals: { f: f } %>");

Variable f in ERB expression is local, it is not defined in that template. That's why it causes an error.

Rewinding this scenario to where this variable was defined for a regular GET-request leads us to _form.html.erb template where it is set as a block parameter for a form of @usercat . For your AJAX-call @usercat is not defined as well.

I would recommend to rewrite _stoptime.html.erb template and replace f.input with a regular text_field_tag (or time_field_tag ?). In your case, value is defined separately through @ustoptime variable, which is set in both controller methods for regular and AJAX calls. So the only thing f variable brings to your partial is a name of input tag. You can spy it using a regular GET-request to the current codebase.

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