I'm new to Rails. I want to write a delete for my reviews. I followed the code in the tutorial. Here is the code in the show page
<% link_to "Delete this review", review_path(#review), method: :delete, data: { confirm: "Are you sure?" } %>
Here is the code in the controller
def destroy
# find the individual review page, delete it then redirect to home page
#review = Review.find(params[:id])
#deleting the review
#review.destroy
#redirect to home page
redirect_to root_path
end
# end of destroy
There is no error, no confirmation, no action at all. When I checked the command line, I noticed the reviews#show is working whenever I click the destroy link -
Started GET "/reviews/4" for ::1 at 2022-05-03 19:58:13 +0630
Processing by ReviewsController#show as HTML
Parameters: {"id"=>"4"}
Review Load (0.2ms) SELECT "reviews".* FROM "reviews" WHERE "reviews"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
↳ app/controllers/reviews_controller.rb:51:in `show'
Rendering layout layouts/application.html.erb
Rendering reviews/show.html.erb within layouts/application
Rendered reviews/show.html.erb within layouts/application (Duration: 0.7ms | Allocations: 271)
Rendered layout layouts/application.html.erb (Duration: 7.5ms | Allocations: 2265)
Completed 200 OK in 10ms (Views: 8.6ms | ActiveRecord: 0.2ms | Allocations: 3049)
How do I fix it?
I somehow was able to fix this. I read a few more blogs. And it's the javascript thing happening.
First, I tried the following two methods but they only make GET requests:
1.
<% link_to "Delete this review", review_path(#review), method: :delete, data: { confirm: "Are you sure?" } %>
2.
<% link_to "Delete this review", review_path(#review), data: { turbo_method: :delete, turbo_confirm: "Are you sure?" } %>
My Solution
When I created my rails project, it didn't include the javascript; application.js in the asset (I don't know why but I'm still trying to find out).
So I created it manually and added the following code:
//= require_tree
//= require jquery
//= require jquery_ujs
Next, I went to my gemfile and added the line gem 'jquery-rails'
And ran bundle install
Then, I went back to my application.html.erb and added the javascript_include_tag:
<%= javascript_include_tag "application", 'data-turbolinks-track': 'reload' %>
Finally I edited the link in the show.html.erb:
<%= link_to "Delete this review", #review, data: { 'method': :delete, 'confirm': "Are you sure?" } %>
And it finally made a DELETE request.
I'm still baffled by my conclusion. There are a lot of discussions going around regarding "method calls" with version changes. My solution might not be the best approach but I can at least continue with this. I would love to hear your thoughts on it as well.
Thank you for all the input.
As taken from the Ruby on Rails Guide 7.0.4:
Clicking links always results in an HTTP GET request. If your
application is RESTful, some links are in fact actions that change
data on the server, and should be performed with non-GET requests.
This attribute allows marking up such links with an explicit method
such as "post", "put", or "delete".
Turbo will scan tags in your application for the turbo-method data
attribute and use the specified method when present, overriding the
default GET action.
<%= link_to "Delete post", post_path(post), data: { turbo_method: "delete" } %>
For confirmations:
<%= link_to "Delete post", post_path(post), data: { turbo_method: "delete", turbo_confirm: "Are you sure?" } %>
Also worth mentioning that the destroy method in my controller is:
def destroy
#event = Event.find(params[:id])
#event.destroy
redirect_to events_path, status: :see_other
end
Replacements for Rails/UJS Functionality - 5.1 Methods
Related
I am a beginner of Ruby on rails, I failed when I try to delete the object that I create. here is the code.
controller
class PuzzlesController < ApplicationController
def index
#puzzles = Puzzle.all
end
def show
#puzzle=Puzzle.find(params[:id])
end
def new
#puzzle = Puzzle.new
end
def create
#render plain: params[:puzzle].inspect
#puzzle = Puzzle.new(puzzle_params)
if(#puzzle.save)
redirect_to #puzzle
else
render 'new'
end
end
def edit
#puzzle=Puzzle.find(params[:id])
end
def update
#puzzle=Puzzle.find(params[:id])
if(#puzzle.update(puzzle_params))
redirect_to #puzzle
else
render 'edit'
end
end
def destroy
#puzzle = Puzzle.find(params[:id])
#puzzle.destroy
redirect_to puzzle_path
end
private def puzzle_params
params.require(:puzzle).permit(:title,:body,:category,:difficulty)
end
end
show
<h2><%= #puzzle.title %></h2>
<p><%= #puzzle.body %></p>
<p><%= #puzzle.category %></p>
<p><%= #puzzle.difficulty %></p>
<hr>
<%= link_to "Edit", edit_puzzle_path(#puzzle), :class => 'btn btn-default'%>
<%= link_to "Delete", puzzle_path(#puzzle),
method: :delete,
data: {confrim: 'are you sure? '},
:class => 'btn btn-danger'%>
when i click on delete, its like re-render the page. i searched a lot on internet and cant find a solution for it.
this is the information on rails server.
Started GET "/puzzles/1" for ::1 at 2017-04-02 18:51:18 +0930
Processing by PuzzlesController#show as HTML
Parameters: {"id"=>"1"}
Puzzle Load (0.5ms) SELECT "puzzles".* FROM "puzzles" WHERE "puzzles"."id" = ? LIM IT ? [["id", 1], ["LIMIT", 1]]
Rendering puzzles/show.html.erb within layouts/application
Rendered puzzles/show.html.erb within layouts/application (1.0ms)
Completed 200 OK in 63ms (Views: 46.2ms | ActiveRecord: 0.5ms)
There are several issues in your code:
1) There is a typo in the link_to parameter list (confirm, instead of confrim):
<%= link_to 'Delete', puzzle_path(#puzzle),
method: :delete,
data: { confirm: 'are you sure? '},
class: 'btn btn-danger' %>
2) At the end of your destroy method you cannot redirect to a singular puzzle path, because you just deleted the puzzle. Redirect to the index page instead:
redirect_to puzzles_path
3) But most important. Links with method: 'delete' only work with JavaScript and Rails 5.0 depends on jQuery. Because you wrote that the links just redirects to the show page, I guess you do not have included the Rails JavaScript files into your asset pipeline:
# Add this to the head of your `views/layout/application.rb`:
<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
# Ensure that your `assets/javascripts/application.js` include the following lines:
//= require jquery
//= require jquery_ujs
Ensure in your browser's concole that the files are loaded without an error.
change your redirect path
redirect_to puzzles_path
I'm new to rails and trying to incorporate Devise to handle user sessions. I want the user to log out, and it is hitting the right route but the session is not deleted and the user is still logged in. Need help please!
The link in the view is:
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
The Server log is:
Processing by Devise::SessionsController#destroy as HTML Parameters: {"authenticity_token"=>"Cyapc8vOXq1FmDZYxrJFPiZFfj77y0aScieiAbMWBxFcoHB3Pr4gvsihf5AQK4VbH8QV24j8IMSpJqnAWEitPQ=="}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" =
? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]] Redirected to
http://localhost:3000/ Completed 302 Found in 2ms (ActiveRecord: 0.1ms)
In your /app/assets/javascripts/application.js file, have you this lines ?
//= require jquery
//= require jquery_ujs
The second line is important for delete methode
Check if current_user returns true or false.
<% if current_user %>
<%= link_to "Sign out", destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to "Sign In", new_user_session_path %> or
<%= link_to "Sign Up", new_user_registration_path %>
<% end %>
QUICK BACKGROUND
I have a model where a facility has_many managers through relationships. The relationship model holds one additional attribute, admin, which is a boolean. Then, for each facility, I have a page that allows an admin/some user to mark managers's as admin or not. They do this through checkboxes. I am using devise for managers. Everything is pretty much done like the first 2 minutes of this railscast:
http://railscasts.com/episodes/165-edit-multiple-revised?view=comments
THE PROBLEM(S)
The issue is, when I submit the form_tag, I get:
1. WARNING: Can't verify CSRF token authenticity
2. It then resets my user session (logs me out of devise), so I have to log back in to continue working.
If I remove protect from forgery from the application controller, everything works smoothly but obviously I don't want to do that as my fix.
So, how can I avoid this CSFR issue with form_tag?
THE FORM (updated)
<%= form_tag admin_relationships_path, method: :put do %>
<table>
<tr>
<th></th>
<th>Person Name</th>
<th>Admin</th>
</tr>
<% #relationships.each do |relationship| %>
<tr>
<td><%= check_box_tag "relationship_ids[]", relationship.id %></td>
**<%= hidden_field_tag :authenticity_token, form_authenticity_token %>**
<td><%= User.find(relationship.user_id).full_name %></td>
<td><%= relationship.admin ? "Yes" : "No" %></td>
<td><%= link_to 'Remove', relationship, method: :delete, **remote: true** %></td>
</tr>
<% end %>
</table>
<%= submit_tag "Make Checked Admins" %>
<% end %>
The contoller.
class RelationshipsController < ApplicationController
def destroy
#relationship = Relationship.find(params[:id])
#relationship.destroy
respond_to do |format|
format.html { redirect_to "/facilities/1679/invite", notice: " Manager has been deleted." }
format.json { head :no_content }
end
end
The log.
Started DELETE "/relationships/52" for 127.0.0.1 at 2013-11-26 14:30:11 -0500
Processing by RelationshipsController#destroy as JS
Parameters: {"id"=>"52"}
WARNING: Can't verify CSRF token authenticity
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 38 LIMIT 1
(0.1ms) BEGIN
(0.1ms) COMMIT
Relationship Load (0.2ms) SELECT `relationships`.* FROM `relationships` WHERE `relationships`.`id` = 52 LIMIT 1
(0.1ms) BEGIN
SQL (0.2ms) DELETE FROM `relationships` WHERE `relationships`.`id` = 52
(0.4ms) COMMIT
Redirected to http://localhost:3000/facilities/1679/invite
Completed 302 Found in 10ms (ActiveRecord: 1.6ms)
Started DELETE "/facilities/1679/invite" for 127.0.0.1 at 2013-11-26 14:30:11 -0500
ActionController::RoutingError (No route matches [DELETE] "/facilities/1679/invite"):
Request Headers:
Accept, Accept-Encoding, Accept-Language, Connection, Cookie, Host, Origin, Referer, User-Agent, X-Requested-With
THE ANSWER
As the poster below mentioned, my CSFR token was not being received on the page. Although, I had the <%= csrf_meta_tag %> in my application layout and admin layout, and I was actually rendering the application layout, the form was on a Devise page.
So I needed to place the <%= csrf_meta_tag %> code in devise.html.erb. You can find the troubleshooting below.
Try adding this to aplication.js:
$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
Answered here: WARNING: Can't verify CSRF token authenticity rails
Be sure you either have this in your application layout in the head section:
<%= csrf_meta_tag %>
Or this hidden field in your form:
<%= hidden_field_tag :authenticity_token, form_authenticity_token %>
I am working through the Getting Started tutorial (creating a Blog) and the link_to Destroy is not functioning properly. In the terminal it always interprets it as #SHOW.
In reading similar issues I have learned that the Delete must be converted to a POST for the browser to interpret it. This doesn't seem to be happening.
I have run into the same problem using Destroy in the Lynda.com Rails course as well, so it leads me to believe it is something in my development environment. I am using Rails 4, Ruby 2.00p274, MySQL, WEBrick for the HTTP server on a MacBook Pro Lion.
in the terminal session when Destroy is selected:
Started GET "/posts/4" for 127.0.0.1 at 2013-08-09 13:45:20 -0600
Processing by PostsController#show as HTML
Parameters: {"id"=>"4"}
Post Load (0.6ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT 1 [["id", "4"]]
Rendered posts/show.html.erb within layouts/application (0.4ms)
Completed 200 OK in 13ms (Views: 8.6ms | ActiveRecord: 0.6ms)
In the ports-controller.rb:
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to action: :index
end
In the index.html.erb:
<% #posts.each do |post| %>
<tr>
<td><%= post.title %></td>
<td><%= post.text %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', { action: :destroy, id: post.id }, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
In the routes.rb
Blog::Application.routes.draw do
resources :posts do
resources :comments
end
root to: 'welcome#index'
end
Try this
<%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %>
Make sure gem 'jquery-rails' is in gemfile and jquery_ujs is included in app/assets/javascripts/application.js file
//= require jquery
//= require jquery_ujs
Source: https://github.com/rails/jquery-ujs
I had the same issue, for rails 4.2.X. Checked all my javascript files but could not make it work. if u look closely at the server request u will be missing 'authenticity_token' in the params, so user gets logged out.
In rails 4.1 and above u have to use button_to instead of link_to
I solved the problem, just by adding in assets/javascripts/application.js
//= require jquery_ujs
Make sure that you have a Delete REST method via rake routes.
DELETE /articles/:id(.:format) articles#destroy
I've got the same problem only with this blog version as I'm doing both.
http://blog.8thcolor.com/en/2011/08/nested-resources-with-independent-views-in-ruby-on-rails/
I'm also trying to learn how to use the web console and pry within it.
My problem is that binding.pry doesn't show up in destroy method but will in show. That tells me it must be a bad link right? It's not getting to the destroy method even. Thank you all for your answers. We do have to try things don't we?
Trying
<td><%= link_to 'Destroy', { action: :destroy, id: post.id }, method: :delete, data: { confirm: 'Are you sure?' } %></td>
is not going to work for that one.
Here's what he has
<td><%= link_to 'Destroy', [comment.post, comment], :confirm => 'Are you sure?', :method => :delete %></td>
because you only want to delete the comment here.
But combining things so far like the following gives no errors but I still have no binding.pry from the destroy method in the controller.
<td><%= link_to 'Destroy', [comment.post, comment], method: :delete, data: { confirm: 'Are you sure?' } %></td>
and I never get the confirmation like you would expect.
So do try to figure out what's going on with the jquery as suspect.
I can confirm that was my case but the rest I'll leave for nubes because this will show up in a google search.
Started GET "/posts/4" for 127.0.0.1 at 2013-08-09 13:45:20 -0600
This is the problem. The delete link is using GET http verb even though you used method: delete in your link.
Check out the following SO thread
include below line in js
//= require jquery_ujs
include gem:
gem 'jquery-rails'
Destroy Link:
<%= link_to "Logout", destroy_user_session_path %>
I had the same issue and realized that I had created my rails app with -J which is the same as --skip-javascript.
You need JavaScript enabled for this to work; the lack of a popup to confirm the delete is a dead giveaway.
I had exactly this problem and it was caused by triple-clicking the Guide's code block and copy/pasting the code straight into my editor (ST2 on OSX).
You should check that the generated HTML for the link looks like this:
<a data-confirm="Are you sure?" data-method="delete" href="/posts/3/comments/3" rel="nofollow">Destroy Comment</a>
If it doesn't, but instead looks like the below, then the Javascript won't be applied:
Destroy Comment
The large gaps between the href and the unparsed Ruby are caused by the non-breaking spaces (unicode character \u00a0) used in the Guide being copied into your script.
I'm not sure why this doesn't cause a script parse error.
I had the same problem as Barry. Make sure you're copy/pasting correctly in your /app/views/index.html.erb file and inspect the html that is rendered.
I had same problem. In my case, a i had change \app\views\layouts\application.html.erb file from
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
to
<%= stylesheet_link_tag 'default', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'default', 'data-turbolinks-track' => true %>
to avoid my very first Rails problem. But it apparently mangled JavaScript execution and caused Destroy issue.
Therefore rollback your \app\views\layouts\application.html.erb file to its original state, and treat this problem as here
Rails ExecJS::ProgramError in Pages#home?
in evedovelli answer (about coffeescript gem in windows).
I got the same problem. I work out by this way:
My env. is:
A. ruby 2.2.4p230 (2015-12-16 revision 53155) [x64-mingw32]
B. Rails 4.2.5
C. Browser: Firfox 44.02
add include js in html page because delete function will use js to handle.
<%= javascript_include_tag "application" %>
add skip_before_action :verify_authenticity_token to controller for prevent InvalidAuthenticityToken in AdsController#destroy
add link_to into your web page
<%= link_to 'Delete', post, method: :delete, data: {confirm: "Are you sure?"}%>
Now, I can use link_to to delete a record from my page.
Using the button_to method instead of link_to seemed to work, minus the fact that it was not confirming(which I felt was important).
In my case, I was using react-on-rails and had multiple layouts.
Adding <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> to my hello-world layout fixed the problem.
I'm a newbye that is trying to do little things in Rails, at the moment I have created an app that build some links and I want to refresh the content of a Div when they are clicked.
In my application.html.erb I have the layout with the next head:
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
(I have read about change the second line for :defaults but if do that I get a 404 error defauls.js)
I have an index.html.erb that render a partial with this:
<%= render :partial => 'masvisitadas' %>
In my _masvisitadas.html.erb I have the code that generate the links:
<%= link_to solution.SolutionName, "/soluciones/despliega/" + solution.Id.to_s, :remote=>true %>
This generate the next html:
http://localhost:3000/soluciones/despliega/501D0000000QWp6IAG
In my controller I have the next def:
def despliega
respond_to do |format|
format.js {}
end
end
Finally I have created despliega.js.erb:
jQuery(function($) {
var html = "<%= escape_javascript(render('despliega')) %>";
$("#customTopLeft").prepend(html)
$("customTopLeft").html("<%= escape_javascript(render(:partial => 'despliega')) %>");
});
In the log of the web server when i click a link it seems all going well:
Started GET "/soluciones/despliega/501D0000000QXM0IAO" for 127.0.0.1 at 2012-08-
20 12:16:53 +0200
Processing by SolucionesController#despliega as JS
Parameters: {"id"=>"501D0000000QXM0IAO"}
Rendered soluciones/_despliega.html.erb (0.0ms)
Rendered soluciones/_despliega.html.erb (0.0ms)
Rendered soluciones/despliega.js.erb (15.6ms)
Completed 200 OK in 31ms (Views: 31.3ms | ActiveRecord: 0.0ms)
And in the firebug I can see the call with any error but nothing happends.
This is killing my head :) Thanks in advance for any help here.
Regards.
What's in _despliega.html.erb?
Try changing despliega.js.erb to this (and only this):
$('#customTopLeft').html("<%= escape_javascript(render :partial => 'despliega') %>");
Edit - oh, and make sure you have the jQuery libraries included ..