简体   繁体   中英

Rails remote form collection_select onchange error

I'm trying to have a remote form automatically submit when a select option is changed. Everything works when I remove remote: true from the form tag, except I don't want the page to reload each time.

I am using Rails 5.1.4.

Code

<%= form_for @foo, remote: true do |f| %>

    ... fields

    <%= f.collection_select :bar_id, @list, :id, :name,
       {include_blank: '-'}, { onchange: 'this.form.submit();'} %>

<% end %>

Controller

def update
  respond_to do |format|
    if @foo.update(foo_params)
      format.html { redirect_to @foo }
      format.json { render :show, status: :ok, location: @foo }
    else
      format.html { render :edit }
      format.json { render json: @foo.errors, status: :unprocessable_entity }
    end
  end
end

I'm getting the following error when the selection is updated in the view:

ActionController::InvalidAuthenticityToken

I'm assuming the this.form.submit(); is the problem. How can I get this form to submit successfully?

Try to the following simple way adding authenticity_token: true to your form tag like below

<%= form_for @foo, remote: true, authenticity_token: true do |f| %>

It should work, at least working for me.

Updated After Comment

You need to work with partial if you use remote: true like if your form in new.html.erb then cut out form part and create a partial for the form like _form.html.erb then render this into new.html.erb like

new.html.erb

<div id="my-form">
   <%= render partial: "form" %>
</div>

and the create a js.erb file based your main file like new.js.erb and put this line like

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

On your controller add format.js like below

format.html { redirect_to @foo } 
format.js 
format.json { render :show, status: :ok, location: @foo }

For complete jQuery/AJAX reference with RoR-5 you can read this tutorial it will help to brush up your jQuery/AJAX skill

Hope that will work

add this line to your form.

<%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>

and your form should be like this:

   <%= form_for @foo, remote: true do |f| %>
        <%= tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token) %>
        ... fields

        <%= f.collection_select :bar_id, @list, :id, :name,
           {include_blank: '-'}, { onchange: 'this.form.submit();'} %>

    <% end %>

The authenticity token is a random value generated in your view to prove a request is submitted from a form on your site, not somewhere else. This protects against CSRF attacks

You can avoid above error by two ways

1) Add following code in application controller

skip_before_filter :verify_authenticity_token  

Reference Link: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

2) Add authenticity_token in the form

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

OR <%= csrf_meta_tags %>

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