Ruby on Rails 'link_to' method creates wrong link - ruby-on-rails

I am having issues with the link_to method in Rails. I have the routes established, but the urls aren't working correctly.
3000/gov_official => my root page
3000/gov_official/1 => desired show page url
3000/gov_official.1 => what I am getting...
Any help would be greatly appreciated.
My code snippet:

Try the following in your routes instead of manually defining the index/show routes.
resource: :gov_official, only: [:get]

Probably having an issue link_to, try this one.
<%= link_to gov.name, gov_official_path(id: gov.id) %>

From my own experience, the problem is that Rails can't figure out which path are you trying to link to. Because, your resource is not in plural form gov_officials, you don't have 2 clearly separate paths:
gov_officials_path - takes 1 argument format. Generates: gov_officials.format.
gov_official_path - takes 1 argument model. Generates: gov_officials/:id
So, to solve your problem the Rails way, use pluralization of your resources correctly.

Related

Rails: link_to only if route exists

I'm writing a Rails Engine and in one of my views I'd like to create a link to main_app if a named route exists.
I will give an example to clarify the question:
The Main application may or may not define in routes.rb:
resources :my_resource, only: :index
In my rails engine I need to add a link to my_resource_path only if main_app defined that route. I think it should be something like the following:
<%= link_to "Link", main_app.my_path if my_resource_path_exists? %>
I tried:
<%= link_to "Link", main_app.my_resource_path if
main_app.respond_to?(:my_resource_path) %>
but, when the path does not exist, that raises NoMethodError:
undefined method `my_resource_path' for #<Module>
How my_resource_path_exists? method could be implemented? I'm using ruby 2.2 and rails 4.2
The question is related to: Determine if path exists as route in Rails controller
But in this case, I have a named route (my_resource_path), so I need something slightly different, but can't figure out by myself.
I found a solution wich does not require to recover from fail. It's possible to check if the route is defined using url_helpers:
Rails.application.routes.url_helpers.method_defined?(:my_path)
So, the code could be written like that:
<%= link_to "Link", main_app.my_resource_path if
Rails.application.routes.url_helpers.method_defined?(:my_resource_path) %>
You could either use main_app.try(:my_path) or rescue NoMethodError to return false.

Invalid route name for GET and POST

I'm working through an older tutorial that was done for Rails 3. I'm using Rails 4.1.4.
One of the instructions is to change the routes file to include the following:
get '/boards/:board_id/conversations/:id/reply' => "conversations#reply", :as => :reply_board_conversation
post '/boards/:board_id/conversations/:id/reply' => "conversations#save_reply", :as => :reply_board_conversation
Obviously that gives me an error:
Invalid route name, already in use: 'reply_board_conversation'
It seems to me that the route is somehow trying to replicate the behaviour of a new and create action. Get for new and Post for create with a single route.
The problem is I can't figure out how to rewrite the route so it works. I've googled for solutions but can't seem to find anything. If anyone could point me in the right direction it would be hugely appreciated.
It looks like the only issue is with the duplicated "named route" name reply_board_conversation. So you could simply change one. I'd probably rename the save version to save_reply_board_conversation. Then it should work. Just remember to refer to the route this way in the future. This would primarily be used in a form tag. So, for exmaple:
<= form_tag :url => save_reply_board_conversation_path do %>
Note the use of save_reply_board_conversation_path instead of reply_board_conversation_path given that the form would be submitting a POST request instead of a GET request.
The names for these routes should be different although since the composition of the URL is the same so you really only need a name for the first one.
The trick with named routes is they generate the URL only, they do not set the HTTP request method. That has to be done independently.
That means you can call the same named route two different ways:
<%= link_to('View', board_path(#board)) %>
<%= link_to('Delete', board_path(#board), method: :delete) %>
These actually render as the same URL but one will hit the GET route, the other the DELETE one.

Making a controller exist on as a sub-controller, how to fix form routes in rails

I have a ChaptersController that does not have a direct route (i.e. site/chapters/:id) but only exists as a sub route for a BooksController (i.e. site/books/:id/chapters/:id). however, when I try to go to books/:id/chapters/new , I get the following routing error:
Showing .../app/views/chapters/_form.html.erb where line #1 raised:
No route matches {:controller=>"chapters"}
how can I fix this?
It seems like you are using nested routes in this manner:
resources :books do
resources :chapters
end
in which case you should have the named routes 'book_chapter' and 'book_chapters'. You can check this by running rake routes.
In your _form.html.erb partial you need to change this line:
<%= form_for(#chapter) do |f|%>
You need to specify the target URL of the form explicitly, and probably also handle different URLs for create and update scenarios. Try something like this:
<%= form_for(#chapter, :url => (#chapter.new_record? ? book_chapters_path(#book) : book_chapter_path(#book, #chapter) )) do |f| %>
I suppose there is wrong path in /app/views/chapters/_form.html.erb
Check what url is in tag. I suppose you forgot to change it to nested in books.
You may as well paste _form.html.erb here, so i will point it out :)

Routing error with Rails 3 with members

I have the following route in rails 3:
resources :jobs do
member do
post :seller_job_submitted
end
end
And the following form
=form_for job, :url=>seller_job_submitted_job_path(job), :remote=>true do |f|
I know it's not very restful, but it's kind of a stop gap for now. In any case, I keep getting this error when submitting the form
Started POST "/jobs/74/seller_job_submitted" for 127.0.0.1
ActionController::RoutingError (No route matches "/jobs/74/seller_job_submitted"):
but when I run rake routes | grep seller_job_submitted, I think the correct results come up:
seller_job_submitted_job POST /jobs/:id/seller_job_submitted(.:format) {:action=>"seller_job_submitted", :controller=>"jobs"}
Any ideas about what might be going on?
Thanks!
Assuming you have defined method seller_job_submitted in model and controller.
Replace your code with
resources :jobs
match "jobs/:id/seller_job_submitted" => "jobs#seller_job_submitted", :as => "seller_job_submitted"
Then in form_for tag use :url=>seller_job_submitted_path
This should fix your problem: you did not define seller_job_submitted_job_path explicitly.
Perhaps use put instead of post? Or use :post as the method in the submit form.
You can tell if this is the issue by looking at what the REST method is for the generated form (look for the hidden field in the page source).
So in short, maybe Rails is somehow expecting a POST on that URL but it's receiving a PUT.
Yes, this is a regression bug with Rails 3.
It turns out you need to be careful about using POST in your routes.rb.
resources :jobs do
member do
post :seller_job_submitted # will not work
put :seller_job_submitted # will just work
end
This is even though the FORM method says POST.

Form Action garbled, Rails 2.3.3

I seem to have a problem that I can't find the solution for myself, I hope someone can help.
I have a form defined like so:
<% form_for #leads do |f| %>
I have a resource called #leads (map.resource :leads)
But when I look in the HTML code of the page it generates, I see as a form action the following
<form action="/lead.%23%3Clead:0x10333e858%3E" class="edit_lead" ... etc
The lead.%23%3Clead:0x10333e858%3E as a form action does work, however rails doesn't know what to do with it after it updates. Does anyone know how I can make this a normal URL so that rails can redirect after the update again?
Thank you very much
Regards, Marco
I think you have to rename your route from
map.resource :leads
to
map.resources :leads
because you have multiple leads (and not only one -> so no "resource", its "resources")
If you are using a singular resource you should not pass the object to the url helper, ie. lead_path not lead_path(#lead).
However it does look like a typo and your route should be map.resources :leads

Resources