Rails HTML requests :Post but does a :Get - ruby-on-rails

I have some code for attending/withdrawing from a competition:
<% 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 %>
When I click on the action I go to an error page:
No route matches [GET] "/competitions/1/withdraw"
Why isn't it doing a POST request? How do I fix this?
Not sure if it effects it, but my current js is
//= require jquery
//= require bootstrap
//= require turbolinks
//= require_tree .
thanks

Related

Destroy Method in Ruby Application does not work

For my ruby on rails application the destroy method doesn't work.
This is how the controller.rb looks like:
def destroy
#post = Post.find(params[:id])
#post.destroy!
redirect_to '/posts/new(.:format)'
end
The show.html.erb:
<div class="btn">
<%= link_to "Delete", :method => :delete %>
</div>
And the application.js:
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .
When the post url is http://localhost:3000/posts/bestpostever
and I click the delete button, I get directed to http://localhost:3000/posts/bestpostever?method=delete but that's it. The post still gets shown.

Rails GET method is called instead of DELETE

I am trying to delete a record using :method => :delete but its calling GET instead. It redirects to show and displays 404 not found. But if i go back and refresh, the record is acctualy deleted.
<% #photos.each do |photo| %>
<div class='photogallery'>
<%= link_to image_tag(photo.image_url(:thumb)) if photo.image? %>
<div class="name"><%= photo.caption %></div>
<div class="actions">
<%= link_to "edit", edit_admins_photogallery_path(photo) %> |
<%= link_to "remove",admins_photogallery_path(photo), :method => 'delete',:confirm => 'Are you sure?' %> |
</div>
</div>
<% end %>
application.js
//= require jquery
//= require jquery_ujs
//= require jquery-fileupload/basic
//= require jquery-fileupload/vendor/tmpl
//= require dataTables/jquery.dataTables
//= require bootstrap
//= require bootstrap-select
//= require jquery.timepicker
//= require jquery.ui.tabs
//= require jquery.ui.datepicker
//= require jquery.ui.accordion
//= require jquery.ui.autocomplete
//= require strftime-min.js
//= require turbolinks
//= require_tree .
i have included in my layout file and its been loaded fine.
<%= csrf_meta_tag %>
<%= javascript_include_tag "application", "data-turbolinks-track" => true %>
The weird part is it used to work fine few days back,now it has stopped working for all the controllers.
edit: routes.rb
devise_for :users
root 'index#index'
resources :reprint
devise_scope :user do
get "/admins/", :to => "devise/sessions#new"
end
namespace :admins do
resources :location,:dashboard,:lodge,:room,:booking,:rate_calendar,:photogallery
end
resources :index do
collection do
match 'search' => 'index#search', via: [:get, :post], as: :search
match 'location' => 'index#location', via: [:get, :post], as: :location
match 'add_cart' => 'index#add_cart', via: [:get, :post], as: :add_cart
end
end
resources :room_availability
edit: photogallery_controller.rb
def destroy
#photos = Photogallery.find(params[:id])
if #photos.destroy
redirect_to admins_photogallery_path, notice: "Photo was successfully destroyed."
else
render :action => 'index'
flash[:error] = "Photo could not be deleted."
end
end
I ran across the same problem and when I changed link_to to button_to everything started working correctly. Maybe because link_to is mainly used for GET calls and button_to for POST calls (in my case DELETE also).
def destroy
#photos = Photogallery.find(params[:id])
if #photos.destroy
redirect_to admins_photogalleries_path, notice: "Photo was successfully destroyed."
else
render :action => 'index'
flash[:error] = "Photo could not be deleted."
end
end
I believe you have it set up correctly, you just made a typo in the redirect_to call. admins_photogallery_path is the show page. admins_photogalleries_path is the index page. There's no way you're making a GET request and reaching the destroy method unless you specified that specifically in the routes. The GET and DELETE verbs both talk to the same path - if you were indeed using a GET request, you'd simply go to the show page and nothing would happen. That anything got deleted at all suggests that the DELETE request is being made successfully.

client side validation not loading

I am following the rails cast 263 on client side valuation. I have the code in place, though it is not validating the errors live for me. The errors only show after submitting the form.
application.html.erb:
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag :defaults, "rails.validations" %>
<%= csrf_meta_tags %>
client_side_validations.rb:
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
unless html_tag =~ /^<label/
%{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
else
%{<div class="field_with_errors">#{html_tag}</div>}.html_safe
end
end
form.html.erb:
<%= form_for #user, :validate => true do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :email %><br/>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :password %><br/>
<%= f.password_field :password %>
</div>
<div class="field">
<%= f.label :username %><br/>
<%= f.text_field :username %>
<div class="field">
<%= f.label :zip_code %><br/>
<%= f.text_field :zip_code %>
</div>
</div>
application.js:
//= require jquery
//= require jquery.ui.all
//= require jquery_ujs
//= require jquery.magnific-popup.js
//= require jquery.purr
//= require rails.validations
//= require best_in_place
//= require_tree .
Original Suggestion: Link to JS in application.js.
Rather than linking to the rails.validations.js from application.html.erb:
<%= javascript_include_tag :defaults, "rails.validations" %>
You may want to do this in your app/assets/javascripts/application.js file:
//= require rails.validations
That's how I connect into additional JavaScript files.
I don't know much about Rails 2, but I think that there was a shift in Rails 3 so that now application.html.erb is used to link to application.js and then all other JS files are linked to from there. It looks like :default might not work how it used to. RailsCasts are super helpful but some of the episodes that were created a few years ago have code samples that have changed in recent versions of Rails.
Edit 1: Make sure rails.validations.js was installed into app/assets/javascripts.
In the RailsCast the rails g client_side_validations:install command puts rails.validations.js into the project. Apparently this doesn't always work and you can call rails g client_side_validations:copy_assets to get it dropped into app/assets/javascripts (See: Can't include js file for client slide validation).
Edit 2: In Rails 4, fix compatibility bugs.
It looks like client_side_validations doesn't work in Rails 4 and the gem is no longer maintained (See: https://github.com/bcardarella/client_side_validations).
In Rails 3, in action_view\helpers\form_helper.rb, the apply_form_for_options! method is:
def apply_form_for_options!(object_or_array, options)
In Rails 4, it is:
def apply_form_for_options!(record, object, options)
If you look at the client_side_validations code, its version is:
def apply_form_for_options!(object_or_array, options)
super
options[:html][:validate] = true if options[:validate]
end
That matches the Rails 3 definition. We only get two arguments but then we call super which blows up because Rails 4 expects three arguments.
If you are feeling brave, you could fork the client_side_validations gem and work through these Rails-4-compatibility issues. But I would suspect that there might be quite a few pieces to update since this gem had to be so tightly integrated with the FormHelper.
Sorry that doesn't immediately solve your problem. Good luck!

rails / bootstrap delete link issue: data-method delete not working

I am using gem 'twitter-bootstrap-rails' for rails bootstrap
I have a few links on a page
Rails code
<td><%= link_to 'Destroy', swimming_classschedule, method: :delete, data: { confirm: 'Are you sure?' } %></td>
<li> <%= link_to "Logout", destroy_user_session_path, method: :delete, :class => 'navbar-link' %> </li>
html code:
Logout
<td>Destroy</td>
<td>Destroy</td>
Whenever I click to delete a student I got logged out. I am totally confused
I had the same problem.. I read in the forums that it was due to javascript issues.
In application.js, I previously removed the original files because I thought they weren't needed as I was using bootstrap.js. I put it back in the file and now the delete method works again!
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap
//= require_tree .
based on this answer Delete link sends "Get" instead of "Delete" in Rails 3 view
I added
<%= csrf_meta_tag %>
in header, which fixed the issue

How to require assets only for development environment

I'm using the assets pipeline from Rails 3.1 and I want to include some javascript files only if it's the development environment.
Example:
//= require application/jquery
//= require application/jquery_ujs
// next ones only for development environment
//= require application/badglobals
//= require application/consul
Its there a standar way of doing this? Any suggestions?
Update
Looking at the Sprockets current documentation, seems like there is not a way to do this.
Why not just require these in the view? Is it important that they are loaded in the asset? To load them in the view:
<% if Rails.env.development? %>
<%= javascript_include_tag "application/badglobals" %>
<%= javascript_include_tag "application/consul" %>
<% end %>
If you rename your application.js file (or whichever file you're calling //= require ... in) to application.js.erb, you can take advantage of require_asset. i.e:
//= require application/jquery
//= require application/jquery_ujs
<% if Rails.env.development? %>
<%= require_asset 'application/badglobals' %>
<%= require_asset 'application/consul' %>
<% end %>
Source: https://github.com/sstephenson/sprockets/issues/90

Resources