简体   繁体   中英

Rails JQuery sending GET instead of POST request

I've been stuck on a rails issue for a few days and haven't been able to find a solution. My code used to work, but there were some major changes (Required) to the javascript and it no longer works.

My users can attend and withdraw from an event. This takes the user making a button click and then sending a post request, but for some reason the request is processed as a Get request and and fails because there is no route for a get request (needs to be post).

View:

    <% if @competition.users.exclude?(@user)  %>
      <%= link_to 'Attend Competition', attend_competition_path(@competition.id), :method => :post %>
    <% else %>
      <%= link_to 'Withdraw', withdraw_competition_path(@competition.id), :method => :post %>

application.js

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require_tree .

application.html.erb

<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
<%= csrf_meta_tags %>

routes.rb

  resources   :competitions do
    post 'attend', on: :member
  end
  resources   :competitions do
    member do 
      post 'withdraw'
    end
  end

controller:

def attend
@competition = Competition.find(params[:id])
if @competition.users.include?(current_user)
  flash[:error] = "You're already attending this competition."
elsif current_user.daily == []
  flash[:error] = "You must have a working device to compete."
else
  current_user.competitions << @competition
  flash[:success] = "Attending competition!"
end
redirect_to @competition
end


def withdraw
p "WITHDRAWING"
@competition    = Competition.find(params[:id])
p @competition
attendee = Attendee.find_by_user_id_and_competition_id(current_user.id, @competition.id)
if attendee.blank?
  flash[:error] = "No current attendees"
else
  attendee.delete
  flash[:success] = 'You are no longer attending this competition.'
end
p attendee
redirect_to @competition
end

the actual error:

ActionController::RoutingError (No route matches [GET] "/competitions/9/withdraw"):

Thanks

** EXTRA **

Complete show.view

<p id="notice"><%= notice %></p>
<p>
  <%= @competition.title %>
</p>
<p>
  <b>Length:</b>
  <%= @competition.length %>
</p>
  <b>Start:</b>
  <%= @competition.start.strftime("%d %m %Y") %>
</p>
  <b>End:</b>
  <%= @competition.end.strftime("%d %m %Y") %>
</p>
<p><strong>Attendees: </strong>
    <% if @competition.users.exclude?(@user)  %>
      <%= link_to 'Attend Competition', attend_competition_path(@competition.id), :method => :post %>
    <% else %>
      <%= link_to 'Withdraw', withdraw_competition_path(@competition.id), :method => :post %>
    <% end %>
</p>
<% a = 1 %>
<% for attendee in @competition.users %>
  <p2><strong><%= a %> </strong><%= link_to attendee.name, attendee %></p2>
  <% if attendee.daily != [] %>
   <p><%= attendee.daily.first(7).sum %></p>
  <% end %>
  <% a = a + 1 %>
<% end %>
</br>


<%= link_to 'Edit', edit_competition_path(@competition) %> |
<%= link_to 'Back', competitions_path %>

HTML output from Rails

<a href="/competitions/4/withdraw" data-method="post" rel="nofollow">Withdraw</a>

** MOAR **

complete errors from the logs

ActionController::RoutingError (No route matches [GET] "/competitions/6/withdraw"):
  actionpack (3.2.3) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  actionpack (3.2.3) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
  railties (3.2.3) lib/rails/rack/logger.rb:26:in `call_app'
  railties (3.2.3) lib/rails/rack/logger.rb:16:in `call'
  actionpack (3.2.3) lib/action_dispatch/middleware/request_id.rb:22:in `call'
  rack (1.4.5) lib/rack/methodoverride.rb:21:in `call'
  rack (1.4.5) lib/rack/runtime.rb:17:in `call'
  activesupport (3.2.3) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
  rack (1.4.5) lib/rack/lock.rb:15:in `call'
  actionpack (3.2.3) lib/action_dispatch/middleware/static.rb:62:in `call'
  railties (3.2.3) lib/rails/engine.rb:479:in `call'
  railties (3.2.3) lib/rails/application.rb:220:in `call'
  rack (1.4.5) lib/rack/content_length.rb:14:in `call'
  railties (3.2.3) lib/rails/rack/log_tailer.rb:14:in `call'
  rack (1.4.5) lib/rack/handler/webrick.rb:59:in `service'
  /Users/Marcus/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
  /Users/Marcus/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
  /Users/Marcus/.rvm/rubies/ruby-1.9.3-p448/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'


  Rendered /Users/Marcus/.rvm/gems/ruby-1.9.3-p448@rails3tutorial2ndEd/gems/actionpack-3.2.3/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (0.5ms)

HTML from Browser:

<a href="/competitions/3/withdraw" data-method="post" rel="nofollow">Withdraw</a>

FULL PAGE [could be long]:

<html><head>
<title>BOTB</title>
<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet" type="text/css">
<script data-turbolinks-track="true" src="/assets/application.js" type="text/javascript">    </script><style type="text/css"></style>
<meta content="authenticity_token" name="csrf-param">
<meta content="Cl7ar8gwVcRsJzrKjp92KB6p6PihvVu0jAwngi18dWU=" name="csrf-token">
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

  <style id="clearly_highlighting_css" type="text/css">/* selection */ html.clearly_highlighting_enabled ::-moz-selection { background: rgba(246, 238, 150, 0.99); } html.clearly_highlighting_enabled ::selection { background: rgba(246, 238, 150, 0.99); } /* cursor */ html.clearly_highlighting_enabled {    /* cursor and hot-spot position -- requires a default cursor, after the URL one */    cursor: url("chrome-extension://pioclpoplcdbaefihamjohnefbikjilc/clearly/images/highlight--cursor.png") 14 16, text; } /* highlight tag */ em.clearly_highlight_element {    font-style: inherit !important; font-weight: inherit !important;    background-image: url("chrome-extension://pioclpoplcdbaefihamjohnefbikjilc/clearly/images/highlight--yellow.png");    background-repeat: repeat-x; background-position: top left; background-size: 100% 100%; } /* the delete-buttons are positioned relative to this */ em.clearly_highlight_element.clearly_highlight_first { position: relative; } /* delete buttons */ em.clearly_highlight_element a.clearly_highlight_delete_element {    display: none; cursor: pointer;    padding: 0; margin: 0; line-height: 0;    position: absolute; width: 34px; height: 34px; left: -17px; top: -17px;    background-image: url("chrome-extension://pioclpoplcdbaefihamjohnefbikjilc/clearly/images/highlight--delete-sprite.png"); background-repeat: no-repeat; background-position: 0px 0px; } em.clearly_highlight_element a.clearly_highlight_delete_element:hover { background-position: -34px 0px; } /* retina */ @media (min--moz-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {    em.clearly_highlight_element { background-image: url("chrome-extension://pioclpoplcdbaefihamjohnefbikjilc/clearly/images/highlight--yellow@2x.png"); }    em.clearly_highlight_element a.clearly_highlight_delete_element { background-image: url("chrome-extension://pioclpoplcdbaefihamjohnefbikjilc/clearly/images/highlight--delete-sprite@2x.png"); background-size: 68px 34px; } } </style><style>[touch-action="none"]{ -ms-touch-action: none; touch-action: none; }[touch-action="pan-x"]{ -ms-touch-action: pan-x; touch-action: pan-x; }[touch-action="pan-y"]{ -ms-touch-action: pan-y; touch-action: pan-y; }[touch-action="scroll"],[touch-action="pan-x pan-y"],[touch-action="pan-y pan-x"]{ -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y; }</style></head>
  <body style="">
    <header class="navbar navbar-fixed-top navbar-inverse">
  <div class="navbar-inner">
    <div class="container">
      <a href="/" id="logo">Battle Of The Bands</a>
      <nav>
        <ul class="nav pull-right navbar-nav " id="menu">
          <li><a href="/">Home</a></li>
          <li><a href="/competitions">Competition</a></li>
            <li><a href="/users">Users</a></li>
            <li id="fat-menu" class="dropdown">
              <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                Account <b class="caret"></b>
              </a>
              <ul class="dropdown-menu">
                <li><a href="/users/1">Profile</a></li>
                <li><a href="/devices">Connect Device</a></li>
                <li><a href="/competitions/new">Create Competition</a></li>
                <li><a href="/users/1/edit">Settings</a></li>
                <li class="divider"></li>
                <li>
                  <a href="/signout" data-method="delete" rel="nofollow">Sign out</a>
                </li>
              </ul>
            </li>
        </ul>
      </nav>
    </div>
  </div>
</header>
    <div class="container">
      <p id="notice"></p>

<p>
  Tester March 8
</p>

<p>
  <b>Length:</b>
  5
</p>
  <b>Start:</b>
  03 03 2014
    <p></p>
  <b>End:</b>
  03 03 2014
<p></p>
<p><strong>Attendees: </strong>
      <a href="/competitions/3/withdraw" data-method="post" rel="nofollow">Withdraw</a>
</p>
  <p2><strong>1 </strong><a href="/users/1">Marcus Smith</a></p2>
   <p>49774</p>
<br>


<a href="/competitions/3/edit">Edit</a> |
<a href="/competitions">Back</a>

      <footer class="footer">
  <small>
    by <a href="http://www.twitter.com/_mhsmith_"> Marcus Smith</a>
  </small>
  <nav>
    <ul>
      <li><a href="/about">About</a></li>
    </ul>
  </nav>
</footer>
      <!-- <pre class='debug_dump'>--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
action: show
controller: competitions
id: '3'
    </pre> -->
    </div>

</body></html>

I suspect this is because you don't have jquery_ujs.js included.

// application.js
//
//= require jquery
//= require jquery_ujs

In your application.js manifest, you should be including jquery_ujs - it't the unobtrusive javascript code that will transform the GET request into a POST because of the data-method field in your tag.

If you do have jquery_ujs.js included,m then sevenseacat's remark about javascript errors is probably it - if you have any javascript errors that are being raised before the jquery_ujs.js is executed, it will not be able to interpret your link.

I don't know if anyone will see this since a lot of time has elapsed since the question was asked but I was encountering the same issue so if anyone is looking for an answer and jquery-ujs wasn't the issue, here's what finally solved it for me - double check your code and make sure you do not have:

$(document).unbind('click') ...

anywhere in your code. This causes the needed javascript Rails uses to convert a GET request into a POST or DELETE request to not run. Hope that helps solve this issue that bugged me for a very long time for someone else.

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