Getting 404 despite having defined "resources" in config/routes.rb - ruby-on-rails

I have this in my config/routes.rb
resources :my_objects
and I have app/controllers/my_objects_controller.rb
def edit
respond_to do |format|
#my_object = MyObject.find(params[:id])
format.json {
render :json => #my_object
}
end
end
But I get a 404 from my JQuery when I attempt to contact this URL (via GET) using
http://localhost:3000/my_objects/edit/8
I have also tried
http://localhost:3000/my_objects/edit?id=8
got still get a 404. What is the right URL I need to use to get data from my edit link?

The RESTful routes created by resources follow this pattern:
method path controller action
---------------------------------------------------------
GET /my_objects #index
POST /my_objects #create
GET /my_objects/new #new
GET /my_objects/:id/edit #edit
GET /my_objects/:id #show
PATCH|PUT /my_objects/:id #update
DELETE /my_objects/:id #destroy
See: Rails Routing from the Outside In

It should be
http://localhost:3000/my_objects/8/edit
not
http://localhost:3000/my_objects/edit/8
See #max answer for clarification.

Related

Rails Routing Incorrectly links to show.html

I'm learning Rails and have encountered some behavior I don't understand. I'm trying to create a simple CRUD app. On the 'new' view after data entry fields and submit button I am trying to add a link that will go to another page (I'll call it 'fnord').
Instead of linking to fnord, it's going to show.html. Given that rails is convention based I wonder if this is a default behavior of some kind, but I haven't been able to figure out what triggers it or the proper way of routing to fnord.
This is Rails 3.2.21, Ruby 1.9.3. I originally generated the model, views and controller using scaffold and then started tweaking things.
Here's my controller (minus unrelated actions - index, destroy, etc):
class EmployeesController < ApplicationController
def show
#employee = Employee.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #employee }
end
end
def new
#employee = Employee.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #employee }
end
end
def fnord
#nothing yet - just trying to get the page to appear right now
end
Here's the relevant code from new.html.erb:
<h2>New Employee</h2>
<%= render 'form' %>
<!-- content, data entry fields, submit button, etc -->
<div>
<%= link_to 'Fnord', employees_fnord_path %>
<div/>
Here's the view, fnord.hmtl.erb:
<h2>Fnord</h2>
<br/>
<p>this is fnord.html</p>
Here's my routes.rb:
MyApp::Application.routes.draw do
resources :employees
get 'employees/fnord'
root :to => 'employees#new'
end
I ran 'rake routes' and get the following output:
employees GET /employees(.:format) employees#index
POST /employees(.:format) employees#create
new_employee GET /employees/new(.:format) employees#new
edit_employee GET /employees/:id/edit(.:format) employees#edit
employee GET /employees/:id(.:format) employees#show
PUT /employees/:id(.:format) employees#update
DELETE /employees/:id(.:format) employees#destroy
employees_fnord GET /employees/fnord(.:format) employees#fnord
root / employees#new
As far as I can see this all looks right, but when I click on the link in new.html it returns show.html, not fnord.html.
The url that shows up in the browser is even locahost:3000/employees/fnord, but the content is from show.html.
I read the routing documentation (http://guides.rubyonrails.org/routing.html) but didn't see any explanations.
I've tried restarting rails (many times) and clearing my browser cache as well and those steps didn't help.
Can anyone enlighten me as to what I'm missing? Thank you very much.
The route for /employees/fnord matches the show route because the show route is looking for URL's in the format: /employees/:id
When you go to /employees/fnord it interprets fnord as the ID of some employee, and it routes it to the show method.
One way to fix it is to declare the /employees/fnord route before the resources routes, so that it matches first:
MyApp::Application.routes.draw do
get 'employees/fnord'
resources :employees
root :to => 'employees#new'
end
Another way is to simply change the name of the URL so that it doesn't match the pattern of /employees/:id:
MyApp::Application.routes.draw do
resources :employees
get 'employees1/fnord', to: 'employees#fnord'
# or whatever
get 'foo', to: 'employees#fnord'
# etc...
get 'employees/foo/fnord', to: 'employees#fnord'
root :to => 'employees#new'
end

Routing Error uninitialized constant

I am trying to learn RoR.
MY controller is
class SectionController < ApplicationController
def new
if request.post?
u=SectionMst.new( :section_name => params[:section_name])
u.save
redirect_to("/section")
else
render
end
end
def index
#sections = SectionMst.all
end
def destroy
u=SectionMst.destroy(params[:id])
u.save
redirect_to("/section")
end
def edit
#user = SectionMst.find(params[:id])
end
end
and index.html.erb is
<%= link_to "Edit", edit_section_path(section.id), method: :edit %>
rake routes is
section_new POST /section/new(.:format) section#new
POST /section/:id/edit(.:format) section/:id#edit
section_index GET /section(.:format) section#index
POST /section(.:format) section#create
new_section GET /section/new(.:format) section#new
edit_section GET /section/:id/edit(.:format) section#edit
section GET /section/:id(.:format) section#show
PUT /section/:id(.:format) section#update
DELETE /section/:id(.:format) section#destroy
routes.rb is
post "section/new"
post "section/:id/edit"
resources :section
i am getting the
Routing Error
uninitialized constant Section
if i delete the second line of routes.rb
then i get
Routing Error
No route matches [POST] "/section/3/edit"
not able to get why???
Get rid of the first and second lines in your routes.rb. They're redundant. The resources will create these lines automatically.
The resources :section should be written as resources :sections. Notice that it's plural.
In your index.html.erb, you shouldn't mention method: at all. It's automatically set, and :edit as method doesn't exist. Method refers to put or get or delete, but you normally don't have to mention it.
You do not need this lines in your routes.rb
post "section/new"
post "section/:id/edit"
Change the third line to:
resources :sections #plural
If you delete them, you can hit the edit view using
<%= link_to "Edit", edit_section_path(section.id), method: :edit %>
which will hit your app at section/3/edit with a GET request.
In your edit.html.erb, you can then have fields to capture edits and do a PUT to /section/3.
Note that RAILS uses HTTP verbs to define the CRUD operations. Ref here.
Check your controller's file name because it should be plural. It is supposed to match the class name. So, you should rename app/controllers/section_controller.rb to app/controllers/sections_controller.rb.

Passing params using redirect to different action in controller

This is first action in controller:
def investor_following
#investor = params[:user][:investor_id]
# blah
end
def change_amount
investor = "xyz"
redirect to :action => :investor_following, :user[:investor_id] => investor
end
I am getting error how can I redirect to action investor following, what would be right syntax to do with params.
You should create a named route for your action in your routes.rb. I'm not sure what you investor_following function will do, so I am not certain if it should be a GET, POST, or PATCH. If you intend to modify your model, use a POST/PATCH, if not, use a get.
Once you have a named route, you will get a path helper like investor_following_path which you can send parameters as ruby objects:
#routes.rb
get '/investor_following', to: 'controllername#investor_following', as: 'investor_following'
#in your controller
redirect_to investor_following_path(user: {investor_id: investor})
This is untested but in general what you should do.
Here is info on redirect_to:
http://api.rubyonrails.org/classes/ActionController/Redirecting.html
Here is the info on routing for your named path:
http://guides.rubyonrails.org/routing.html

Rails redirect_to not working, redirecting to show instead of custom action

So I have a ChatsController, and from my index action, I'm trying to redirect to a custom action, "decide":
def index
#chat = Chat.customfind(params[:search])
if(#chat.is_a?(Array))
session[:chats] = #chat
redirect_to :action => 'decide'
else
respond_to do |format|
format.html { redirect_to #chat if !#chat.nil? }
end
end
def decide
#chats = session[:chats]
#choice = Chat.find(params[:id])
redirect_to #choice if !#choice.nil?
end
..where #choice is going to be decided by the params of the form on the decide page. But for some reason, instead of redirecting to decide, Rails redirects to show:
Started GET "/chats/decide" for 127.0.0.1 at 2012-03-14 17:13:36 -0400
Processing by ChatsController#show as HTML
Parameters: {"id"=>"decide"}
..............
Can anyone explain how to fix this?
Edit:
I'm assuming this is what you want... the relevant parts of my routes.rb:
match "chats/decide" => "chats#decide"
resources :chats do
member do
post 'send_message'
end
end
get "chats/logout"
..yeah it's a bit of a hodgepodge :/
It seems you are trying to achieve the following:
Find all chats matching a given search string
If 1 chat is found, redirect to it
If 2+ chats are found, redirect to /chats/decide so the user can pick one
I would implement this as follows:
1) Update routes.rb as follows:
resources :chats do
member do
post :send_message
end
collection do
get :decide # Produces the '/chats/decide/' route
end
end
2) Change your chats#decide action to this:
def decide
#chats = session[:chats]
end
3) When you list the available chats in your decide.html.erb file, link them directly to the appropriate show link.
4) Be explicit about your redirect in chats#index:
redirect_to :controller => 'chats', :action => 'decide'
Your chats#decide action should not respond differently based on whether it's receiving an id or not. You can link directly to the specific chats in that view.

Redirect to a custom path on failure to upate

I have a route set up like this -
match "/:id" =>"car#edit", :as => :edit_car
match "/:id/thanks" =>"cars#thanks", :as => :thanks
www.myurl.com/12345 will go to the edit action of car.
My update action looks like this
def update
#car = Car.find(params[:id])
respond_to do |format|
if #car.update_attributes(params[:car])
format.html { redirect_to(thanks_path(#car)) }
else
format.html { render action: "edit" }
end
end
end
On a successful update it redirects to www.myurl.com/12345/thanks - which is good - works as expected.
However, when it has errors while updating it renders the edit action as -
www.myurl.com/cars/12345
I'd like it to rerender the edit action as -
www.myurl.com/12345
I'd like make sure that error messages are still sent through. Is this possible?
The route you're seeing is the edit action of the resource route, not your separately defined edit action. Hence it includes the controller in the path.
If you want that the path not include the cars controller you can include this in the route definition:
resources :cars, :path => '/'
From experience I advise that you don't do that as things get messy when you want to expand your application.
I suggest you do away with the defined edit action and edit your cars from the show action of your resource route. Also, you could display the success message from the update action without redirecting by having an update view file.
If you do want to redirect you can modify resource routes as so:
resources :cars, :path => '/' do
member do
get 'thanks'
end
end

Resources