Can't use delete method on Ruby on rails - ruby-on-rails

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

Related

Rails 7 Destroy not working and only running Show

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

Ruby on Rails - why i am facing possible unmatched constraints[:exercise_id]

def edit
#exercise = Exercise.find(params[:exercise_id])
#play = #exercise.plays.find(params[:id])
end
def update
#exercise = Exercise.find(params[:exercise_id])
#play = #exercise.plays.find(params[:id])
if #exercise.plays.update_attributes(play_params)
redirect_to #exercise_path
else
render action: :edit
end
end
partial view that is being rendered to show all created plays has
<p><%= play.name %></p>
<p><%= play.sets %></p>
<p><%= play.reps %></p>
<%= link_to "edit", edit_exercise_play_path( #exercise, play) %>
that is plays_controller :edit, :update method, Actually i have two classes, one is ExerciseController and other one is PlaysController, ExerciseController has_many plays, i am rendering two partials one to create play and other one to show that play on same page on the partial which is rendering the play after creation, but now i want to add edit feature with edit_exercise_play_path,
<%= link_to "Edit", edit_exercise_play_path(#play) %>
after this i am facing unmatched constraint error.Thanks
resources :exercises do
resources :plays
end
Show.html.erb from ExercisesController
<h2>Your Workout Details </h2>
<p><%= #exercise.workout %></p>
<p><%= #exercise.mode %></p>
<p><%= #exercise.date.strftime("on %A at %H:%M Dated as %d %B") %></p>
<p><%= #exercise.length %></p><br />
<h3> Games you Played </h3>
<%= render #exercise.plays %>
<h3>Add new Game </h3>
<%= render 'plays/form' %>
<%= link_to "Edit", edit_exercise_path %> | |
<%= link_to "Destroy", exercise_path(#exercise), :confirm => "Are you
sure?", :method => :delete %> | |
<%= link_to "Back", root_path %>
" Logs "
Started GET "/exercises/5" for 127.0.0.1 at 2018-09-25 18:12:21 +0500
Processing by ExercisesController#show as HTML
Parameters: {"id"=>"5"}
Exercise Load (0.0ms) SELECT "exercises".* FROM "exercises" WHERE "exercises"."id" = ? LIMIT ? [["id", 5], ["LIMIT", 1]]
Rendering exercises/show.html.erb
Play Load (0.0ms) SELECT "plays".* FROM "plays" WHERE "plays"."exercise_id" = ? [["exercise_id", 5]]
Rendered collection of plays/_play.html.erb [6 times] (14.0ms)
Rendered exercises/show.html.erb (39.7ms)
Completed 500 Internal Server Error in 136ms (ActiveRecord: 0.0ms)
As per your routes, the path helper edit_exercise_play_path also require value for :exercise_id key. But you haven't passing any. Changing the link_to to below should fix your problem
<%= link_to "Edit", edit_exercise_play_path(#exercise, #play) %>
Update:
As per our discussion over the chat, the link_to edit should look like below
<%= link_to "Edit", edit_exercise_play_path(#exercise, play) %>
as you are rendering a partial with <%= render #exercise.plays %> which creates a play variable.
undefined method `model_name' for nil:NilClass
For this, you should change <%= render 'form' %> to <%= render 'form' , exercise: #exercise, play: #play %> and in the _form.html.erb change the first line of the form to <%= simple_form_for ([exercise, play]) do |f| %>
undefined method `update_attributes' for
Play::ActiveRecord_Associations_CollectionProxy:0x0000000f69c710
The reason for this error is in your update method you have have #exercise.plays.update_attributes(play_params). This means you are calling update_attributes on collection. You should change
if #exercise.plays.update_attributes(play_params)
to
if #play.update_attributes(play_params)

link_to 'delete' is not destroying a record

I'm following along with the rails tutorial by Michael Hartl Chapter 13 but instead of microposts, I'm creating animals.
My view of animals shows a "delete" hyperlink that is supposed to delete an animal record from my list but the view action doesn't seem to get to the point where it uses the destroy method at all.
I read through all the answers in a similar post here but did not find those answers to help in my case.
I'm currently in a development environment on AWS cloud9 as instructed in the tutorial. I really appreciate any pointers as I have been struggling with this one for days.
Here is my code from the view:
<li id="animal-<%= animal.id %>">
<%= link_to gravatar_for(animal.user, size: 50), animal.user %>
<span class="user"><%= link_to animal.user.name, animal.user %></span>
<span class="ear_tag"><%= animal.ear_tag %></span>
<span class="timestamp">
Posted <%= time_ago_in_words(animal.created_at) %> ago.
<% if current_user?(animal.user) %>
<%= link_to "delete", animal, method: :delete, data: { confirm: "You sure?" } %>
<% end %>
</span>
</li>
This view is called from a feed view:
<% if #feed_items.any? %>
<ol class="animals">
<%= render #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
Which comes from the home page view:
<div class="col-md-8">
<h3>Animal Feed</h3>
<%= render 'shared/feed' %>
</div>
I have reviewed the <%= link_to... line many times and it seems to be correct. My controller code is:
class AnimalsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def destroy
#animal.destroy
flash[:success] = "Animal deleted"
redirect_to request.referrer || root_url
end
def correct_user
#animal = current_user.animals.find_by(id: params[:id])
redirect_to root_url if #animals.nil?
end
end
I noticed that I never see the flash "Animal deleted" so that tells me I probably don't get to that point in the controller method.
My model code is:
class Animal < ApplicationRecord
belongs_to :user
default_scope -> {order(created_at: :desc) }
validates :user_id, presence: true
validates :ear_tag, presence: true, length: {maximum: 20}
end
Here is my application.js file from app/assets/javascripts:
//= require jquery
//= require bootstrap
//= require rails-ujs
//= require turbolinks
//= require_tree
Here is what the server log says after I click on the "delete" tag in my rendered view in the browser:
Started DELETE "/animals/308" for 23.25.133.17 at 2018-09-06 21:11:06 +0000
Processing by AnimalsController#destroy as HTML
Parameters: {"authenticity_token"=>"vwF6cWow+6B3BxOiJElVY0aQmMGr4WLWDOCxgB0C03nRLcQDKC3YCUqBr4ahVwlSKN7bEYRrmGytyI1fPgvavw==", "id"=>"308"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 102], ["LIMIT", 1]]
Animal Load (0.2ms) SELECT "animals".* FROM "animals" WHERE "animals"."user_id" = ? AND "animals"."id" = ? ORDER BY "animals"."created_at" DESC LIMIT ? [["user_id", 102], ["id", 308], ["LIMIT", 1]]
Redirected to https://cabfa13dd4f34e67b634d4f52a7a046f.vfs.cloud9.us-west-2.amazonaws.com/
Filter chain halted as :correct_user rendered or redirected
Completed 302 Found in 4ms (ActiveRecord: 0.3ms)
I also found one of my tests to fail:
FAIL["test_animal_interface", AnimalsInterfaceTest, 1.5248641059999954]
test_animal_interface#AnimalsInterfaceTest (1.53s)
"Animal.count" didn't change by -1.
Expected: 38
Actual: 39
test/integration/animals_interface_test.rb:33:in `block in <class:AnimalsInterfaceTest>'
Filter chain halted as :correct_user rendered or redirected
The problem is you have #animals(which is not defined) instead of #animal, so redirect_to root_url if #animals.nil? always succeeds which results in destroy action failing always. You should change #animals to #animal
def correct_user
#animal = current_user.animals.find_by(id: params[:id])
redirect_to root_url if #animal.nil?
end

use multiple form in a view. which is post to the different action with ajax

Getting trouble with known at the title.
I have two forms in new.html.erb view. One is form_for, other one is form_tag, both as partials.
form_for is to save some data to models.
form_tag is to do little action with params. and give back the processed data to partilal(js). here I'm stuck. this not working.
form_tag is not working. after submitting, the action "urlchanger" don't reflect any data to partial "urlchanged". in My plan, this should get #url, but get errors (detail below).
This is the error respowned by submitting form_tag.
ActionController::RoutingError: No route matches [POST] "/notes/new"
..
Processing by Rambulance::ExceptionsApp#not_found as JS
Parameters: {"utf8"=>"✓", "url"=>"<iframe src=\"http://hogehoge.com/hoge" frameborder=0 width=510 height=400 scrolling=no></iframe>", "urlchanger"=>"変換"}
Rendered errors/not_found.json.jbuilder (0.2ms)
Completed 404 Not Found in 66ms (Views: 48.1ms | ActiveRecord: 0.0ms)
as the non partial. everything works fine.
but, I want them to work in single view.
notes
--new.html.erb
----_form.html.erb
----_urlchanger.html.erb
----_urlchanged.js
----_urlchanger.js.erb
!-------------notes/new.html.erb-------------!
<%= render 'form' %>
<%= render 'urlchanger' %>
!-------------notes/_urlchanger.html.erb-------------!
<%= bootstrap_form_tag(controller: "notes", action: "urlchanger", remote: true ) do |f| %>
<%= f.text_field :url, hide_label: true, :class => "form-control", placeholder: "ペーストエリア" %>
<%= f.submit "変換", data: { disable_with: '送信中'} %>
<div id="urlchanged" >
<%= render "urlchanged" %>
</div>
<% end %>
!-------------notes/_urlchanged.html.erb-------------!
<input type="text" class="form-control" value="<%= #url %>">
!-------------notes/_urlchanger.js.erb-------------!
$('#urlchanged').html('<%= j(render("urlchanged")) %>');
!-------------routes-------------!
resources :notes do
collection do
post :create
post :urlchanger
end
end
!-------------Notes controller-------------!
def urlchanger
url = params[:url]
if /(https?:\/\/\D*\w*)/ =~ url
#url = $&
end
end
Please help. Thank you.
What happens when you change your notes/_urlchanger.js.erb to notes/urlchanger.js.erb?
OR try this
def urlchanger
url = params[:url]
if /(https?:\/\/\D*\w*)/ =~ url
#url = $&
end
respond_to do |format|
# format.html { redirect_to(:back) } # no idea what you might want to do here
format.js { render partial: "notes/urlchanger" }
end
end
solved problem!!
I don't know why it works ('A')
But like the code blow works good.
---------------Note.controller----------------------
def urlchanger
url = params[:url]
if /(https?:\/\/\D*\w*)/ =~ url
#url = $&
end
respond_to do |format|
# format.html { redirect_to(:back) } # no idea what you might want to do here
format.js
end
end
------------------notes/_urlchanger.html.erb-------------------
<%= bootstrap_form_tag( url: notes_urlchanger_path, remote: true ) do |f| %>

Can't get errors to be displayed in an Rails "remote: true" form?

I'm trying to display errors messages in my ajax form (the code is based on this question):
posts_controller.rb:
def create
#post = current_user.posts.build(params[:post])
if params[:commit] == "Publish"
#post.status = "Published"
elsif params[:commit] == "Save Draft"
#post.status = "Draft"
end
respond_to do |format|
format.html do
if #post.save && #post.status == "Published"
flash[:success] = "Post published"
redirect_to #post
elsif #post.save && #post.status == "Draft"
flash[:success] = "Post saved as draft"
render 'edit'
else
render 'new'
end
end
format.js do
#post.save
end
end
end
posts/create.js.erb:
<% if #post.errors.any? %>
alert('There are errors.');
<%= render :partial=>'js_errors', :locals=> { :target=> #post } %>
<% else %>
$('.busy').html('Saved.');
<% end %>
js_errors.js.erb:
<% target.errors.full_messages.each do |error| %>
$('.busy').append('<p><%= escape_javascript( error ) %></p>');
<% end %>
posts/new.html.erb:
<%= form_for(#post, remote: true, :html => { :multipart => true }) do |f| %>
<%= render 'fields', f: f %>
<div class="form-actions">
<%= f.submit "Publish", class: "publish btn btn-primary pull-left" %>
<%= f.submit "Save Draft", class: "save-draft btn btn-default pull-left" %>
<div class="busy pull-left">
</div>
</div>
<% end %>
But for some reason nothing displays (.busy always remain empty).
In the console I can see that js_errors.js.erb is being displayed:
Started POST "/posts" for 127.0.0.1 at 2013-01-04 18:02:18 +0800
Processing by PostsController#create as JS Parameters: {"utf8"=>"✓",
"authenticity_token"=>"Qfn6HsPPDxyB1t4bM/OQKPbJ/aoAMkp74y0Z6xkoXCY=",
"post"=>{"title"=>"", "content"=>"", "tag_list"=>""},
"_wysihtml5_mode"=>"1", "commit"=>"Save Draft"} User Load (0.7ms)
SELECT "users".* FROM "users" WHERE "users"."remember_token" =
'ljl0ZsuoiHg0Jilz8bgy-g' LIMIT 1 (0.2ms) begin transaction
(0.2ms) rollback transaction Rendered posts/_js_errors.js.erb
(3.8ms) Rendered posts/create.js.erb (7.5ms) Completed 200 OK in
25ms (Views: 11.2ms | ActiveRecord: 1.0ms | Solr: 0.0ms)
What could be the problem?
(I do see the validation messages if I remove remote:true from the form).
EDIT:
I noticed alert('There are errors.'); is not being triggered. Strange.
It looks like a naming problem. You're asking to render the partial js_errors, which would be called _js_errors.js.erb; but you say your file is actually called js_errors.js.erb (no leading underscore).
Try adding the underscore and see if that helps matters.
I have been facing a similar problem a few days ago. I used remote => true option in my form to use Ajax in my Rails 3 application. After that, I have been looking for solution for validating my form fields. After trying a good number of jQuery / Javascript approaches (none of them worked for me though) I came to know about a superb gem called client_side_validations. It is very easy to install by following the instructions on github link (https://github.com/bcardarella/client_side_validations). It works like charm for client side validation of form fields, an awesome gem indeed. Hope this helps with people who are tired of looking for a simple solution for client side validation of model fields after using Ajax in Rails 3 application.

Resources