Why is my Rails web app calling the wrong action? - ruby-on-rails

I'm diving into Ruby on Rails and I'm experiencing a weird bug, using Rails 3.0.1 and Ruby 1.8.7. Using the generated scaffold code, my "Show" action is getting called when I'm expecting my "Destroy" action to get called. Here's the code...
routes.rb
webappdotcom::Application.routes.draw do
resources :projects
root :to => "home#index"
end
index.html.erb
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
actual HTML code that is rendered in browser
<td>Destroy</td>
server output when I click on the "Destroy" link
Started GET "/projects/12" for 127.0.0.1 at Wed Oct 20 23:39:37 -0500 2010
Processing by ProjectsController#show as HTML
Parameters: {"id"=>"12"}
Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE ("projects"."id" = 12) LIMIT 1
Rendered projects/show.html.erb within layouts/application (9.0ms)
Completed 200 OK in 77ms (Views: 13.3ms | ActiveRecord: 0.1ms)
You can see the "ProjectsController#show" action is being called, but I want the "Destroy" action to be called. Also, I noticed the browser isn't displaying the confirmation message "Are you sure?" either. Any ideas what could be causing this or what I'm missing?
Thanks so much!

This is because Rails 3 changed the way it uses javascript in forms. It used to add an onclick method to the link, but that goes against unobtrusive javascript. Now it just sets some tag attributes, and hooks into it with javascript in another file.
That page's layout (which is probably application.html.erb unless you've changed it) needs to have this line in the head section:
<%= javascript_include_tag :defaults %>
If this line is missing from your layout, that's the problem. Another possible cause could be if you've added the jQuery library to your app without adding the rails-specific jQuery library. Let me know how this works.

This may help you link_to with :method=>:delete not working ( Rails 3 ). Although in that article the edit is getting called instead. But the solution should work for show as well.

Related

Simple_form_for not using AJAX?

I got a weird problem with my form:
= simple_form_for([#item, #item_comment], :remote => true, id: "new_item_comment", :url => item_item_comments_path(#item)) do |f|
= f.input :comment, :label => false
= f.submit "Save", :class => "btn_save left"
Which in my opinion should call:
Started POST "/de-de/items/20150423/item_comments" for 127.0.0.1 at 2015-04-23 12:29:33 +0200
Processing by ItemCommentsController#create as JSON
but instead I get it as HTML:
Started POST "/de-de/items/20150423/item_comments" for 127.0.0.1 at 2015-04-23 12:29:33 +0200
Processing by ItemCommentsController#create as HTML
It used to work but without changing these parts, it only uses HTML.
Does anyone have an idea on how to solve this?
--- Update 1 ---
I added these lines to my coffeescript:
$('form[data-remote]').submit (e)->
e.preventDefault()
$.rails.handleRemote $('form[data-remote]')
And it works but I'm not really satisfied with this solution since I don't know what caused the problem.
Usually it happened to me in 2 cases:
I had a file input on the form (which forces ruby to skip remote: true option)
I had troubles with jquery-ujs javascript file (which actually processes rails html attrs)
So please check your generated html if it has <form .... data-remote='true'..> and check that jquery-ujs (or whatever handler you want to use) is included in a page javascripts.
If you are still having troubles after this, you can put a breakpoint somewhere in jquery-ujs

Why the destroy/delete link dees not work?

I am stuck at Delete/Destroy. Any help would be appreciated!
I am using Ruby 2.0.0 and Rails 3.2.6 on Mac 10.8.3 with Postgres.
This is the delete link which supposed to work:
<%= link_to 'Destroy', #product, method: :delete, data: { confirm: 'Are you sure?' } %>
But when I click on the Destroy link it directs me to the user's profile. I don't get any confirmation window and no action is done (delete). It seems it is just stayed at the same page. I am using Firefox but in IE and Chrome are the same.
This is what I have:
the gem "jquery-rails" is installed
applications.js (from app/assets/javascripts) has these lines:
//= require jquery
//= require jquery_ujs
//= require_tree .
application.html.erb (from app/views/layouts) has these lines:
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
In view source I see:
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="MVlJi+WJE1cwWoHnBrpRWIa13gqio0iPT3IL6kpQYdE=" name="csrf-token" />
in products_controllers.rb (from app/controllers) I have:
def destroy
#product = Product.where(:id => params[:id]).first
#product.destroy
respond_to do |format|
format.html { redirect_to products_url }
format.json { head :no_content}
end
end
in routes.rb (from config) I have:
resources :products
What is wrong with that Destroy link?
On the same RoR project the Edit link works fine.
So, why the link doesn't work? Is it a Javascript problem or some other problem which I am not seeing?
And here is the server's log: (It seems the "delete" action does not been executed)
Started GET "/products/9" for 127.0.0.1 at 2013-08-01 20:01:08 -0500
Processing by ProductsController#show as HTML
Parameters: {"id"=>"9"}
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = 9 LIMIT 1
Rendered products/show.html.erb within layouts/application (0.5ms)
Completed 200 OK in 27ms (Views: 25.8ms | ActiveRecord: 0.1ms)
One helpful way to handle path issues with Rails is to type "rake routes" in your console, in order to have a list of all the paths available to play with your ressources.
By declaring "resources :products" in your routes.rb file, "rake routes" will provide a list of Prefix/Verb/URI Pattern/Controller#Action for this particular resource. You will have something like:
Prefix Verb URI Pattern
product GET /product/:id(.:format) product#show
PATCH /product/:id(.:format) product#update
DELETE /product/:id(.:format) product#destroy
Take the word of the prefix column (product), add _path to this word (product_path), use the correct method (DELETE), pass the ids as parameters (in this case, you can just do product_path(#product)), and you're done. You will have :
<%= link_to "Delete", product_path(#product), method: :delete, data: { confirm: "Are you sure?" } %>
Perhaps (I'm just guessing, but one day I ran into a similar problem) if you design catalog or shop with a shopping cart based on the book Agile Web Development with Rails, the product model may contain a filter before_destroy :ensure_not_referenced_by_any_line_item that prevents the product from destroy in case if product listed in LineItems. If this is your case, you can clear list of LineItems in the ProductsController before destroying the product. Otherwise sorry.

Rails jQuery adapter rendering thrice

I'm following the Beginning Rails 3, Updated book from Apress 2010. The problem I'm having is with loading a Template dynamically with Ajax using the jQuery adapter. Everything works but it appears to be rendering three times on the page.
Here is how I dynamically load it when the user clicks the "new comment" link.
views/articles/show.html.erb
<%= link_to "new comment",
new_article_comment_path(#article, :format => :js),
:remote => true,
:id => 'new_comment_link' %>
Then I render it as such.
views/comments/new.js.erb
$("<%= escape_javascript render :file => 'comments/new'," +
" :formats => [:html], :handlers => [:erb] %>")
.insertAfter('#comments');
Then I see this in the log.
Started GET "/articles/1/comments/new.js" for 127.0.0.1 at 2013-01-18 14:51:05 -0600
Processing by CommentsController#new as JS
Parameters: {"article_id"=>"1"}
Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT 1 [["id", "1"]]
Rendered comments/new.html.erb (53.8ms)
Rendered comments/new.js.erb (54.6ms)
Completed 200 OK in 57ms (Views: 55.9ms | ActiveRecord: 0.2ms)
Notice it renders my erb and the js file? Somehow that ends up with showing up three times on my page.
Any clues on how to fix this? I'm using Rails 3.2.9, rails.js (latest), and jquery-1.9.0.
Thanks!
Solved it!
Turns out I was adding rails.js and jquery.js TWICE!
Here is the skinny: assets/javascripts/application.js is crucial for including javascript files into your app. Basically whatever gets defined there gets pushed out to the page. You simply need to make sure that it gets defined at least once in the app as such.
views/layouts/application.html.erb
<%= javascript_include_tag "application" %>
And that's it! The Ajax jQuery adapter should just work. Becareful not to add any additional files to the javascript folder as those will get pushed out as well and that's exactly what you don't want. Basically I was defining the adapter both through application.html.erb and manually by downloading both files. Hopefully this will help a lost poor soul somewhere along the way.
Happy Hacking.

Ajax calls in rails when jquery.js included don't work

I'm using Rails 2.3.8.
In my application.rhtml I have:
<%= javascript_include_tag "jquery.js"%>
And in my index.rhtml which uses application.rhtml for a layout I have:
<div id="search_residential"> <%= link_to "Residential",
"javascript:residentialSearchForm()", :onclick=> remote_function(:url => {:propertyType => 'residential', :controller => 'site', :action => 'searchform'}, :update => 'search_form', :method => :get)%></div>`
In my partial that should be rendered I have:
<%logger.debug "Residential Form Partial Rendered"%>
When I click the link my log outputs:
Processing SiteController#searchform (for 127.0.0.1 at 2012-10-05 11:11:02) [GET]
Parameters: {"controller"=>"site", "propertyType"=>"residential", "action"=>"searchform", "authenticity_token"=>"Iw3ID/4Lh5IReUwOnhhSUXfn2IIVUnYpqG1N7DE4BHg="}
Rendering site/searchform
Residential Form Partial Rendered
Rendered site/searchbar/_search_residential (5.2ms)
Rendered site/searchbar/_search_form (5.9ms)
Completed in 9ms (View: 7, DB: 0) | 200 OK [http://localhost/site/searchform?propertyType=residential&authenticity_token=Iw3ID%2F4Lh5IReUwOnhhSUXfn2IIVUnYpqG1N7DE4BHg%3D]
But nothing is shown on the website. If I remove the include for jQuery then the partial is rendered.
remote_function is a prototype helper and depends on prototype.js
Jquery would be conflicting at the $ namespace. Its advisable to not use prototype helpers.
Or You should initialize jquery in a noConflict mode.

Why is the wrong action processing my .ajax request.

This is an issue I have been working around for some time now thinking I would eventually stumble on an explaination. I have not and it's now becoming a little more problematic for me.
I used rails-generate-scaffold to create a simple (users and posts) application. This was done after installing jquery and jquery-ui. I added actions "login" and "auth" to the users controller. Login.html.erb contains some javascript that sends .ajax request to the users#auth action passing the login information (email and password) as parameters.
The the template auth.js.erb exists. The "auth" action responds to format.js. The request looks normal, but rails processes the request with the "show" action rather than the "auth" action.
In other words, a request to userscontrollers#auth (via .ajax) is being processed by userscontroller#show (as JS).
The problem goes away if I remove the "resources :users" route that scaffold added (the correct action is then called). But without this route other useful scaffold stuff becomes unuseable (like users#new).
From Gemfile: gem 'jquery-rails', '>=0.2.6'
Installed jQuery with: rails generate jquery:install --ui
From ../layouts/application.html.erb
<head>
<title>Tab1</title>
<%= stylesheet_link_tag :all %>
<%= stylesheet_link_tag 'jquery-ui-1.8.16.custom.css' %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'jquery.min.js' %>
<%= javascript_include_tag 'jquery.min.js', 'jquery-ui.min.js' %>
<%= csrf_meta_tag %>
</head>
Here is ./log/development.log to shows the request and the response.
Started GET "/users/auth/?email=steve&password=[FILTERED]&_=1326063255777" for 24.11.242.181 at 2012-01-08 17:53:45 -0500
Processing by UsersController#show as JS
Parameters: {"email"=>"steve", "password"=>"[FILTERED]", "_"=>"1326063255777", "id"=>"auth"}
^[[1m^[[36mUser Load (0.2ms)^[[0m ^[[1mSELECT `users`.* FROM `users` WHERE `users`.`id` = 0 LIMIT 1^[[0m
Completed 404 Not Found in 6ms
ActiveRecord::RecordNotFound (Couldn't find User with ID=auth):
app/controllers/users_controller.rb:43:in `show'
Suggests that the request --> GET "/users/auth/?email ... is being processed by UsersController#show as JS
Thanks

Resources