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
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.
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.
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!
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
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