ruby on rails- non-existent route - ruby-on-rails

I have a controller file,
abc_controller.rb.
I have defined the show method inside it.
I have a view file,
show.html.haml
inside app/views/abc/
In my routes.rb file, I am giving the following command
resources :abc
I have a button
= link_to 'abc', abc_path, class: 'btn btn-default'
But when I click on the button, its not going to the new page.
I am getting non-existent route error.
Since I am a newbie to rails, I am not able to figure what the problem is.

You are getting a error because there is no such path as abc_path. Run rake routes and you'll see the routes that Rails understands. In you example, resources :abc produces the following routes.
abc_index GET /abc(.:format) abc#index
POST /abc(.:format) abc#create
new_abc GET /abc/new(.:format) abc#new
edit_abc GET /abc/:id/edit(.:format) abc#edit
abc GET /abc/:id(.:format) abc#show
PATCH /abc/:id(.:format) abc#update
PUT /abc/:id(.:format) abc#update
DELETE /abc/:id(.:format) abc#destroy
The first column are the named routes. So in order to get to the index action of abc_controller, the route is named abc_index_path. There is an abc_path but it needs an id params which means that you need to pass something to it. In your case, there's no definitive value to pass to this method so as a trial just use abc_path(1) which will redirect you to /abc/1. This goes to the show action with params[:id] set to 1.

If you do resources (plural) the resulting route for show requires an id: /abc/:id(.:format), so abc_path requires that you pass that :id or a object. If you are dealing with a singular abc (resource :abc), the resulting path doesn't require that :id, so you code should work (this is less common, but hard to tell with your "abc" example.

Related

route is redirecting to wrong path

This is what my routes currently look like:
which gives
On my homepage I have a create vacancy button
<%= link_to "plaats", new_employer_vacancy_path(:employer_id)%>
Which should be linked to the line from the first image
get '/employers/:employer_id/vacancies/new', to: 'vacancies#new', as: 'new_employer_vacancy'
In the vacancies_controller#new - create I have:
def new
#vacancy = Vacancy.new
#employervacancy = Employervacancy.new
end
def create
#vacancy = Vacancy.create(vacancy_params)
createEmployervacancy
redirect_to employer_vacancy_path(current_employer, #vacancy)
end
def createEmployervacancy
#employer = current_employer
Employervacancy.create(vacancy_id: #vacancy.id, employer_id: #employer.id)
end
But whenever I click the button I get redirected to some other method in my vacancies_controller that is totally irrelevant.
How is this even possible? Don't I clearly define that when that path is clicked he should go to vacancies#new? and not to vacancies#show_specific_employer_vacancies?
EDIT
After following the answers I am indeed being linked to the correct route.
First, it gave me this error.
After trying to pass the current_employer.id instead of #employer like suggested I got following error:
For your routes, you'd better to change into nested route for easily maintaining routes.
Remove these codes:
get '/employers/:employer_id/vacancies/:id', to:"vacancies#show_specific_employer_vacancies", as: "employer_vacancy"
get '/employers/:employer_id/vacancies/edit/:id' ...
get '/employers/:employer_id/vacancies/index' ...
get '/employers/:employer_id/vacancies/new' ...
path '/employers/:employer_id/vacancies/:id' ...
change into:
resources :employers do
resources :vacancies
end
Try to use basic routes here because you use standard simple form url. For example:
<%= simple_form_for(#employee, #vacancy) %>
The simple_form_for will generate url well if you use nested routes above.
Finally, in your link you have to add #employer_id
<%= link_to "plaats", new_employer_vacancy_path(:employer_id => #employer_id)%>
I hope this help you
Your router cannot tell the difference between your employer_vacancy and new_emplyer_vacancy routes because the :id parameter accepts anything. Because of this, when you point your browser to "/employers/5/vacancies/new", the route is taking your employer_vacancy route and assigning {:employer_id => 5, :id => "new"} instead of going to your new_employer_vacancy route (because routes are first-come-first-serve).
To correct this, add a constraint to your first route to ensure that only numbers (and not the string "new") is accepted into the employer_vacancy route:
get '/employers/:employer_id/vacancies/:id',
to: 'vacancies#show_specific_emplyer_vacancies',
as: 'employer_vacancy',
constraints: { id: /\d+/ } # <- This line
As Wes Foster said rails router is trying to find a first match.
It means that given a path /employers/999/vacancies/new your router looks through the routes and when it sees get '/employers/:employer_id/vacancies/:id he thinks that this route matches. So :employer_id is 999 and :id is new.
I'd suggest to put the route with :id at the end of employers routes:
...
get '/employers/:employer_id/vacancies/new'
...
get '/employers/:employer_id/vacancies/:id'
Btw this is better than adding a constraint because:
It is easier
It doesn't pollute routes file
Later you may want to change ids to be hashed or alphabetic and then you'd have to change the constraint

Cant create a link to named routes

I want to create a link to a named route
My routes.db have the following rule
match '/tablero', to: 'tablero#index',via: 'get' , as: 'tablero_main'
I can see the route using rake routes
tablero_main GET /tablero(.:format) tablero#index
But when i use the link_to as follows i get the "undefined local variable or method `tablero_main'" error.
<%= link_to "Tablero",tablero_main %>
Is there anything else i am missing?
You need to append path to the method name, like so:
<%= link_to "Tablero", tablero_main_path %>
Routes
To help you further, you'll need to also consider the role of resources in your routes
As Rails uses a resourceful routing infrastructure, every route you create should be based around a resource. In your case:
#config/routes.rb
resources :tablero, only: :index #-> domain.com/tablero
Admittedly, this will give you the path tablero_index_path, rather than tablero_main_path, but it ensures your routes are not only DRY, but also extensible. Nothing worse than having 100's of "match routes in a route file.
--
Helpers
After that, remember to use the correct route_path helper:
Each "route" path is basically just a helper method (which builds a URL for you). When using link_to, you need to reference the path helper directly. You didn't do this, which lead Rails to come back with the undefined method error

Why did Ruby on Rails' URL Helper put a period in my URL?

I have the following code in my view (RoR 4):
tbody
- #order_submissions.each do |order_submission|
tr
td = order_submission.id
td.table-actions
span = link_to "Show", order_submissions_path(order_submission.id)
td = order_submission.id
successfully displays as the ID number (533ab7337764690d6d000000)
But...
order_submissions_path(order_submission.id)
Creates a URL that comes out as:
order_submissions.533ab7337764690d6d000000
I want it to be
order_submissions/533ab7337764690d6d000000
Where did that period come from?
This is my route:
get 'order_submissions/:id' => 'order_submissions#show'
And when I run rake routes I get:
GET /order_submissions/:id(.:format) order_submissions#show
The (.:format) is probably what's messing it up but I don't know why. I just want it to put a slash in there.
If I change my code to this it fixes it:
span = link_to "Show", order_submissions_path + '/' + order_submission.id
But that's a really, really stupid workaround.
EDIT: Here are my routes:
get 'order_submissions' => 'order_submissions#index'
get 'order_submissions/new' => 'order_submissions#new'
post 'order_submissions' => 'order_submissions#create'
get 'order_submissions/:id' => 'order_submissions#show'
get 'order_submissions/:id/edit' => 'order_submissions#edit'
patch 'order_submissions/:id' => 'order_submissions#update'
get 'order_submissions/:id/delete' => 'order_submissions#delete'
delete 'order_submissions/:id' => 'order_submissions#destroy'
The order_submissions_path (plural) points to /order_submissions. It takes two arguments, the first being the format for the request (e.g. html). Your ID is being passed in for this argument, leading to the resulting URL you're seeing.
You actually want the singular path helper, order_submission_path, which accepts an ID as the first argument.
Because it should be a singular form:
order_submission_path(order_submission.id)
Not
order_submissions_path(order_submission.id)
order_submissions_path points onto index action. You can also remove id from the end.
UPDATE:
Just notice you route file. Do you have any resources defined there? The route you posted wouldn't generate any url_helper as you dind't specify route name (most likely this entry is obsolete, as I expect there is resources :order_submissions somewhere there as well).
You don't get a named route by default. The route you showed from rake routes doesn't list a named route, for example.
GET /order_submissions/:id(.:format) order_submissions#show
Normally, you'd see the named route in front of GET there.
So you can define it yourself and then your route will work:
get 'order_submissions/:id' => 'order_submissions#show', as: :order_submission
Notice the as: :order_submission bit. Now, order_submission_path(order_submission.id) will work. (Note: .id is superfluous if your order_submission responds to to_path and returns id.)
I'm guessing you have another route in your rake routes output that uses the named route you supplied and that doesn't use /:id. Perhaps your index route?

Rails 4 + Devise + Routing Error

I'm attempting to install Devise on a rather simple event creating/displaying Rails 4 app. I have 2 static pages and the index page displaying without authentication, and all is well there. Anything else kicks you to the "sign up" page. From there, when I attempt to create an account for myself (to simply see the other pages- simple vanilla devise installation attempt) I get a "No route matches [POST] "/registrations/user" error when clicking "submit" (f.submit)
I am using Rails 4, have the 3.0.3 version of Devise, bundled it, ran "rails generate devise:install" to install it, ran "rails generate devise user", ran db:migrate, raked the routes, and restarted the Rails server.
I even recreated the button action with the "correct" route and "get post" - no dice.
Anybody have any idea? I'm at a loss here.
Well it's always tricking debugging sever-side code without seeing it in action, but here's what should work.
yourappname/config/routes.rb :
devise_scope :user do
# matches the url '/register' to the registration controller's 'new' action and creates a :register symbol inorder to reference the link dynamically in the rest of the code
get 'register', to: 'devise/registrations#new', as: :register
end
(Assuming your register button is in your app's partial)
yourappname/app/views/layouts/application.html.erb:
<%= link_to "Register", register_path, class: "btn" %>
Now you could actually put that link_to anywhere, in any page, and it'll work. The reason for this is the 'register_path'.
When you create your route, the as: :register parameter creates a global variable that can be accessed throughout your app.
the register_path variable in your link_to method will always call the right action, even if you change your routes file.
It's just syntax. You could create any symbol you want. This would also work:
routes.rb:
# Inside get method, third parameter
as: :bowtiesarecool
someview.html.erb:
# Inside link_to method, second parameter
bowtiesarecool_path
Just match the variable name with the symbol name and a put a _path after it. The link_to method will handle everything else!

Rails get routing with parameter

I want to create a new route in my routes.rb which points to a "courses" controller which has the method pdfdownload. The route is supposed to take 2 parameters: course_id and user_id. I thought it should be like this:
get "/courses/pdfdownload/:course_id/:user_id"
The courses controller and everything works fine until I add the line above. The courses controller has a method called pdfdownload. Nevertheless, when I try to start the server (rails s), I get the following error:
warning: already initialized constant Mime::PDF
warning: previous definition of PDF was here
Exiting
`default_controller_and_action': missing :controller (ArgumentError)
When I type rake:routes I get:
missing :controller
The courses controller is existing and is working very well with many methods. After I altered the line to this:
get "/courses/pdfdownload"
The server starts.
The rails guides says at "3.2 Dynamic Segments", it has to be written this way:
get ':controller/:action/:id/:user_id'
Whats wrong here? Thank you very much!
Update: I'm using the following link in the view:
<%= link_to "PDF", courses_pdfdownload_path(#course.id, user.id) %>
Please have a try
get "/courses/pdfdownload/:course_id/:user_id" => "courses#pdfdownload", :as => "courses_pdfdownload"
try match "/courses/pdfdownload/:course_id/:user_id" => "courses#pdfdownload"
The correct route would be:
get '/courses/pdfdownload/:course_id/:user_id', to: 'courses#pdfdownload'
But for a nicer REST route, I would rather change it to this:
get '/courses/pdfdownload/:id/:user_id', to: 'courses#pdfdownload'
The fact that the action deals with a Course resource is already implied by the name of the controller handling the action. So you don't need to call the Course id :course_id, simply :id is enough.
Edit
Note also that you can customize the name of the route helper like this:
get '/courses/pdfdownload/:id/:user_id', to: 'courses#pdfdownload', as: 'courses_pdfdownload'
Your route helper will then be courses_pdfdownload_path.
As for the errors,
warning: already initialized constant Mime::PDF
warning: previous definition of PDF was here
this is due to Rails registering PDF by default since 2011. No need to register them in config anymore.
https://github.com/rails/rails/commit/d73269ba53992d8a01e5721aad3d23bc2b11dc4f

Resources