In nested route, how is :format set to nil? - ruby-on-rails

I have the following in my routes.rb:
resources :users do
resources :decisions
end
/users/new works fine, but /users/:id/decisions/new gives me:
No route matches {:controller=>"decisions", :format=>nil}
<%= link_to "New decision," new_user_decision_path(#user) %> gives me the same error.
I've looked in my rake routes and the action and the helper are listed. All of the actions listed have a (.:format) suffix option, but I don't understand how all of my DecisionsController actions are working fine without a format option except 'new'.
How is :format set to nil and what is its default?

it looks like you used a singular decision in your url when it should be decisions. Your url should be /users/1/decisions/new.
However, you should be using a named route to stop this from happening. You should see something like new_user_decision via rake routes. You can then use the new_user_decision_path for all of your links.

Related

rails link_to using get instead of post

I'm making a website for a class and I'm trying to implement a friend request function with a model called 'Users' and a join model called 'Relationships'. I have a button on the user#show page that should add a friend by using the create method in the Relationships controller. Here is the code for the button:
<%= link_to "Add as Friend", relationships_path(:friend_id => #user), method: :post %>
When I press the link, however, it tries to access the index method instead. After looking in the console, it looks like the link is sending a GET request, which routes to the index method, instead of a POST request, which routes to the create method. Can someone explain why this error is occurring and how I can fix it?
Edit: As requested, here is what I have in my routes:
Rails.application.routes.draw do
resources :interests
get 'interests/create'
get 'interests/destroy'
get 'home/index'
get 'sessions/create'
get 'sessions/destroy'
resources :users
resources :relationships
resources :subscriptions
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
root 'home#index'
get "/auth/:provider/callback" => "sessions#create"
get "/signout" => "sessions#destroy", :as => :signout
Using a link_to helper indicates to Rails that you'd like to produce an a tag in your HTML. No element of the HTML specification regarding a tags allows for producing POST requests. Because Rails understands the utility of allowing for POST and DELETE requests to be issued using links, however, it provides those options in the link_to helper. It's implementation, though, must use JavaScript under the hood in order to appropriately function.
Check that jquery-ujs is installed, and that your asset pipeline is working correctly in order to use the helper in this way.
You may also evaluate whether using a form_for and a button is better, since that will automatically POST.
I'm pretty sure you are matching the wrong route. Run rake routes and see the route that links to the Relationships#create.
Using 'url' instead of 'path' with the route helper solved the problem for me. So instead of 'relationships_path' use 'relationships_url'.

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

Rails route shows in rake, responds in console,but browser shows undefined method?

I cannot figure out why this route is not working. I have defined it, and it seems that it works everywhere, except for in the browser. I've attached screenshots with the relevant information.
The route for reports_path is showing undefined in the browser, but everywhere else it seems that it's working. What could be causing this?
rake routes shows reports_path, don't use path when naming you routes, you have one more named with path reports_selling_agent_performance_path, remove the path.
in this case:
match 'reports', to: 'reports#index', as: :reports
or
match 'reports', to: 'reports#index'
will work too, you use as: key only if you want to rename the path name that you'll use in code, for example:
match 'my_long_very_long_reports', to: 'reports#index', as: :reports
and you'll use reports_path in code instead of my_long_very_long_reports_path. Or in cases where you use keys like :id or others:
match 'my_reports/:id', to: 'reports#index', as: :reports
where :id will be id of the user for example that you'll send as params[:id]
In your routes file, try changing as: :reports_path to as: :reports otherwise I think you'll need to use reports_path_path in your view.

Getting no route matches on the show action

I'm trying to use the path from the following route, here is what it's like in rake routes
chapter GET /chapters/:id(.:format) {:action=>"show", :controller=>"chapters"}
chapter_path creates a link to /chapters/x which is correct but I get the routing error when trying to access it.
No route matches {:controller=>"chapters"}`
this is my routes (I am using shallow routing to create a books_chapters and book_chapters_new paths.
resources :books do
resources :chapters, :shallow => true
end
when I test the route with rake routes, I get books_chapters, books_chapters_new, chapters and books, so I don't know what's wrong.
when i remove :shallow => true, i can access /books/1/chapters/6 but I just want it to be /chapters/6
this is what my terminal looks like
so /chapters/id and /chapters/id/edit should be working fine.
I've restarted the server with touch tmp/restart.txt and ran rails s to see if the routes worked there too and rake routes is giving me acceptable routes, but they don't work for me.
Are you supplying the parameter for the path helper, something like
chapter_path(#chapter)
I couldn't figure out how to get :shallow routes to work, and there isn't an example on how to use :shallow in the rails guide so, instead I have to just use nested routes like so
resources :books do
resources :chapters
end
now this means the something like chapters_url or chapters_path won't work.
So I have to do something like this everywhere
book_chapter_url(#chapter.book, #chapter)
or
edit_book_chapter_path(#chapter.book, #chapter)
It works but there's a bit of code smell because I use #chapter twice and the whole url should be able to resolve just through the chapter id instead.

Resources