Diagnosing a 404 error in Rails - ruby-on-rails

I am trying to make a POST request to /api/kpi?data=some+stuff:
curl -i http://127.0.0.1:9010/api/create_kpi -F data="some stuff"
but I'm getting a 404.
My routes are:
# config/routes.rb
namespace :api do
resource :kpi, :except => [:edit, :destroy]
end
Which should hit my controller
# app/controllers/api/kpi_controller.rb
class Api::KpiController < ApplicationController
def create
temp = Kpi.new(params[:data])
end
end
So I am guessing the paths are not correct. Right? I am having a hard time understanding whether my route is incorrect, or the controller, or the call.

When you get a 404, check your routes. It usually means there is no route to the controller to reach. Routes are what makes the link between URLs and controllers. If your controller was getting hit, it'd either work or give you a runtime error.
Inspect your routes by running rake routes. It's a very helpful tool. It should give you something like this:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
You can see that it gives you the mapping of what [method, URL] request will hit which [controller, action]. For example, here, POST /users will trigger action create of UsersController.
Given a controller/resource name, Rails will, by convention, go looking for the plural of that name. For example, given resources :user, Rails will go looking for UsersController in file app/controllers/users_controller.rb. (Path/file names have to match the name!)
#yfedblum talks about the use of singular and plural in Rails into more detail.

Related

How to reference this path name in Rails 3.2?

I have the following routes.rb
resource :user, :only => [ :edit, :update ] do
collection do
get :tax_info
get :payment_info
put :payment_info
and would like to reference the get payment_info via an rspec matcher like this:
expect(response).to redirect_to(user_payment_info)
What would be the proper way to reference that path? I have tried user_payment_info and edit_user_payment_info?
Edit #1
Show output of rake routes on this controller
You're missing the _path portion that rails generates for all routes. Your rspec matcher should look like this:
expect(response).to redirect_to(user_payment_info_path)
The information returned when running rake routes will look similar to this:
GET /users/:id(.:format) user#show
tax_info_user GET /user/tax_info(.:format) users#tax_info
payment_info_user GET /user/payment_info(.:format) users#payment_info
PUT /user/payment_info(.:format) users#payment_info
edit_user GET /user/edit(.:format) users#edit
user PATCH /user(.:format) users#update
PUT /user(.:format) users#update
You can see on the left hand side there is a column that denotes the prefix for the url and path helpers that rails is going to generate. You can see this defined in the Rails 3.2 routing documentation.

Rails 4 app links failing to generate correct URL

I have a rails 4 app under development in c9 cloud IDE and I have a view file that displays entries from different models.
My issue is certain links in the file fails when clicked while other links on the same page seems working. I have this code in my app view to generate links
<%= link_to '確認ここへ', "/#{applist.controller_name.strip}/#{applist.wfs_id}/edit" %>
for most of the models it generates correct URL like ide.c9.io/dname/arubaito_boshu/491/edit while certain models fails like https://funin_teate_shikyu/new/518/edit
Any help much appreciated
What you're doing is really the anti pattern of rails links.
To generate links in rails please use the according ..._path method.
You can see your routes with the following command:
$ bin/rake routes
Which would give you some output like this:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
From there you can take your prefix for the path method.
With the routes above it's quite simple:
<%= link_to "New User", new_user_path %>
Which will generate this:
New User
If you have dynamic routes you can define a route like this.
# config/routes.rb
Rails.application.routes.draw do
get '/something/:id' => 'something#show', as: :something
end
then in your controller:
# app/controllers/something_controller.rb
class SomethingController < ApplicationController
def show
puts params[:id]
end
end
Now if you visit /something/this-is-awesome, you can access the passed value (which in this case is: this-is-awesome) by using: params[:id] (see controller code)

User Resources Expanded

In order to more clearly understand exactly what "resources" is doing in the Ruby on Rails routes.rb file, I want to write under it the exact code it is replacing.
When I run rake routes I get this:
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
Can someone help me fill in the blanks below so I can understand this more clearly:
resources 'users'
# get 'users' => 'users#index"
# post ...
# get ...
# get ...
# patch ...
# put ...
# delete ...
The equivalent code could be expressed as:
get 'users', to: 'users#index'
post 'users', to: 'users#create'
get 'users/new', to: 'users#new', as: 'new_user'
get 'users/:id/edit', to: 'users#edit', as: 'edit_user'
get 'users/:id', to: 'users#show', as: 'user'
patch 'users/:id', to: 'users#update'
put 'users/:id', to: 'users#update'
delete 'users/:id', to: 'users#destroy'
Brad werths answer is what you need.
To give you some more context, you also need to appreciate how the resourceful routing system works in Rails...
Resource routing allows you to quickly declare all of the common routes for a given resourceful controller. Instead of declaring separate routes for your index, show, new, edit, create, update and destroy actions, a resourceful route declares them in a single line of code.
Basically, each time you call resources, you're telling rails to build a set of routes for a controller designed around the "resourceful" principle.
"Resourceful" actions through the Internet are defined by wikipedia as follows:
HTTP functions as a request-response protocol in the client-server computing model. A web browser, for example, may be the client and an application running on a computer hosting a web site may be the server. The client submits an HTTP request message to the server. The server, which provides resources such as HTML files and other content, or performs other functions on behalf of the client, returns a response message to the client. The response contains completion status information about the request and may also contain requested content in its message body.
All of this make sense when you understand that Ruby/Rails is object orientated. This means everything you do in your application has to resolve around the initialization & maintenance of "objects".
Objects are basically your models - they are created, edited and destroyed (CRUD -- create read update destroy) with your controller actions. Therefore, to give you a set of standardized routes, you'll be able to use the following:
If you want to see your routes like how brad has outlined, you'll want to run rake routes
--
Good resource here: https://softwareengineering.stackexchange.com/questions/120716/difference-between-rest-and-crud

Why does my controller keep routing my link_to toward "show" action? Rails 4

So I am pretty stumped. I am new to Ruby on Rails (I am using Rails 4) and I have been trying to figure out for the last two days why my link_to tag keeps routing my login action to show instead. I removed the show action from my controller and even deleted show.html.erb and yet Rails remains persistent in trying to route it to a show action that no longer exists.
I removed all my redirect_to functions, and the link_to I create takes me to the correct page localhost:8000/users/login but now displays the error Unknown Action: The action 'show' could not be found for UsersController.
I have read up other SO questions that were similar, and some suggest that it may be an issue with jquery_ujs, which I removed from my file to see if it was the problem, but I still ended up with the same result.
The files in my views directory are as follows:
views
users
new.html.erb
login.html.erb
Here's what my code looks like:
The link_to in users/new (new.html.erb)
<li><%= link_to "Login", users_login_path %></li>
routes.rb
resources :users
root 'users#new'
get 'users/create'
get 'users/login'
users_controller.rb
class UsersController < ApplicationController
def new
end
def create
#user = User.create(:username => params[:username], :password => params[:password])
#user.save
#users = User.all
end
def login
#message = "Success"
end
end #end class
login.html.erb (Just testing an output here to see if it ever gets to this page)
<h3><%= #message %></h3>
Output of rake routes command
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / users#new
users_create GET /users/create(.:format) users#create
users_login GET /users/login(.:format) users#login
I figured out what the problem was:
I needed to remove resources :users from the routes.rb file.
Everything is working as expected now. After doing a little bit of research it seems that the problem with having resources :users in there is that when browsers try to access the page they try to perform a command by using an HTTP method, which is either GET, POST, PUT, DELETE, or PATCH.
When the page looks for an incoming command which in this case was GET /users/login, it tries to map it to a controller action. If the first matching route is resources :users, it will send it to the show action.
It seems that this is due to the default CRUD system Rails uses where each HTTP method represents a CRUD action (correct me if I am wrong):
GET is show
POST is create
DELETE is destroy
PATCH is update
I got most of this research from Rails Routing from the Outside In, Section 2.1.

Rails undefined method `user_index_path`

I'm new to Ruby and Rails and working my way through the Rails Tutorial. Early on, I realized that I accidentally created my model as Users rather than User, so I've been going with that ever since.
It hasn't been an issue until I tried to implement the sign up page, and now whether going to pages or running the test visit signup_path for the sign up page, I keep getting the following error:
undefined method `users_index_path' for #<#<Class:0x007f9e3e1d91b8>:0x007f9e3e1d1ff8>
I can't figure out what's going wrong here. When I run rake routes I get the following:
~/Coding/rails_projects/sample_app (sign-up*) ☔ rake routes
Prefix Verb URI Pattern Controller#Action
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PATCH /users/:id(.:format) users#update
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
root GET / static_pages#home
help GET /help(.:format) static_pages#help
about GET /about(.:format) static_pages#about
contact GET /contact(.:format) static_pages#contact
signup GET /signup(.:format) users#new
From that output, it looks to me like there should be a method users_index_path.
If it helps, my Users controller is the following:
class UsersController < ApplicationController
def new
#user = Users.new
end
def show
#user = Users.find(params[:id])
end
end
Using Rails 4.0.5.
Output from a page giving me the error:
Please keep in mind users_index_path is being called by Rails and not by me.
with
users GET /users(.:format) users#index
POST /users(.:format) users#create
you'll have a users_path method that will generate the /users path. That path will lead to either the index action (with a GET request) or the create action (with a POST request).
Under the hood, form_for #user will call the users_path method and set things up to fire a POST on submit (when #user is a new record). The URL helper method is calculated dynamically from the class name. This is ok if you're using Rails' defaults, but if you've defined custom routes you'll need to specify the URL explicitly.
With this out of the way, let's look at your problem.
A model with a plural name, e.g. class Users, will confuse rails.
When you pass #user to form_for, Rails will look at the class name, notice that it's a plural word, and try its best to deal with the ambiguity.
Normally it would be user_path for singular routes (show, update, delete) and users_path for the plural ones (index, create). Here, however, users_path must be used for the singular routes, and Rails will fallback to use users_index_path for index and create.
This would be all right.... but you have defined the routes using the default statement, probably with something like
resources :users
Which is correct, but not compatible with your model name.
Either rename your routes (bad) or rename your model (good).

Resources