NoMethodError with renamed nested resources (false route using link_to) - ruby-on-rails

I've ran into a problem which causes link_to #resource to fail.
My view:
<% #test_thing = Bar.first #This one belongs to Foo.first %>
<%= link_to "test link", #test_thing %>
produces this error:
NoMethodError
undefined method `bar_path' for #<#<Class:0x007fd799bc1088>:0x007fd799bc8400>
Why does rails not produce the correct route using thing1_thing2_path?
routes.rb:
resources :foo, as: "thing1", path: "thing2" do
resources :bar, as: "thing2", path: "thing2"
end
In my models, "Foo" has_many :bars and "Bar" belongs_to :foo
rake routes:
thing1_thing2_index GET /thing2/:thing1_id/thing2(.:format) bar#index
POST /thing2/:thing1_id/thing2(.:format) bar#create
new_thing1_thing2 GET /thing2/:thing1_id/thing2/new(.:format) bar#new
edit_thing1_thing2 GET /thing2/:thing1_id/thing2/:id/edit(.:format) bar#edit
thing1_thing2 GET /thing2/:thing1_id/thing2/:id(.:format) bar#show
PATCH /thing2/:thing1_id/thing2/:id(.:format) bar#update
PUT /thing2/:thing1_id/thing2/:id(.:format) bar#update
DELETE /thing2/:thing1_id/thing2/:id(.:format) bar#destroy
thing1_index GET /thing2(.:format) foo#index
POST /thing2(.:format) foo#create
new_thing1 GET /thing2/new(.:format) foo#new
edit_thing1 GET /thing2/:id/edit(.:format) foo#edit
thing1 GET /thing2/:id(.:format) foo#show
PATCH /thing2/:id(.:format) foo#update
PUT /thing2/:id(.:format) foo#update
DELETE /thing2/:id(.:format) foo#destroy
root GET / bar#index
I'm using rails 4, but I had the same problem with rails 3.
I fell like it's a bug in rails, or am I doing something wrong?

Do not rename your routes. Remove the as: argument:
resources :foo, path: "thing2" do
resources :bar, path: "thing2"
end
Apart from that, you need to hand it both objects in order to produce the correct path:
<%= link_to "test link", [#test_thing.foo, #test_thing] %>

Have you tried passing the link explicitly? Something like:
<%= link_to "test link", bar_path(#test_thing) %>
...or whatever the correct *_path(variable) you should be using?
(Sorry, the test, and bar, and thing1, thing2 things got really confusing over here :P)

Related

Failed to try to use 2 ids on nestes routes in rails

I'm trying to pass 2 ids to the controller within the update action, but it does not stop, I do not recognize the first id, student_id. This is the definition of the route within routes.rb
post 'registers/students/:student_id/notes/:note_id/edit', to: 'registers/students/notes#update', as: :update_registers_student_note
While this is the part of the form_for, using the corresponding helper
<%= form_for #note, url: update_registers_student_note_path(:student_id,:note_id), method: :post do |f| %>
My question is how can I correctly pass the 2 ids of the corresponding resources, since the form only recognizes me note_id, and not student_id
Thank you
The helper should works. You also can use update_registers_student_note_path(student_id: 1, note_id: 12).
But I suggest you to use nested resources in your routes instead.
You can write somethings like that:
namespace :registers do
resources :students do
resources :notes
end
end
The new url helper will be registers_student_note_path(<note_id>, student_id: <student_id>) with method PATCH.
yes, you did put a right thing for url_helpers. You can try to open rails console and try it with these command
include Rails.application.routes.url_helpers
update_registers_student_note_path(1,2)
you will see => "/registers/students/1/notes/2/edit"

Rails 4 Undefined Local Variable or Method for Download link

I keep getting undefined local variable or method `orders_download_template_path' for #<#:0x0000376c505098>
with the following code. I have also tried download_template_path and #orders_download_template_path (this last one doesn't throw an error, but does nothing either).
Routes.rb:
resources :orders do
collection do
post :import
get :upload_page, as: 'upload_page'
get :search, as: 'search'
get :csv_report, as: 'csv_report'
get :overdue_csv_report, as: 'overdue_csv_report'
get :download_template, as: 'download_template'
end
end
orders_controller.rb:
def download_template
send_file Rails.root.join('public/upload_template.csv'),
type: 'application/csv',
x_senfile: true
end
view:
<%= link_to "Blank Upload Template", orders_download_template_path %>
The File has been Placed under /public
Based on the Rails routing guide, you have a syntax error.
http://guides.rubyonrails.org/routing.html#adding-collection-routes
This should fix it
download_template_orders_path
If you run rake routes on your console, you should see the following line (among others):
download_template_orders GET /orders/download_template(.:format) orders#do
as you can see, if you're setting this route on a COLLECTION, the path generate would be download_template_orders_path.
If you set it on a MEMBER, you would see this:
download_template_order GET /orders/:id/download_template(.:format) orders#
Answering your question, the correct path would be download_template_orders_path

Routing Issue for Model that Rails Can't Determine Word Roots

I have a model named Faq and it looks like Rails is having a hard time with the dynamic paths generated from resources :faq.
Here is what rake routes puts out.
admin_faq_index GET /admin/faq(.:format) admin/faq#index
POST /admin/faq(.:format) admin/faq#create
new_admin_faq GET /admin/faq/new(.:format) admin/faq#new
edit_admin_faq GET /admin/faq/:id/edit(.:format) admin/faq#edit
admin_faq GET /admin/faq/:id(.:format) admin/faq#show
PUT /admin/faq/:id(.:format) admin/faq#update
DELETE /admin/faq/:id(.:format) admin/faq#destroy
The problem is when I use form_for like so:
<%= form_for([:admin, #faq]) do |f| %>
I get this error:
undefined method `admin_faqs_path' for #<#<Class:0x007fdda4627a58>:0x007fdda41a5098>
Try changing routes.rb to
resources :faqs
Then verify that #faq is not nil.
Based on the fact that you're using a form, I'm guessing your FAQ is not a singular resource.
You just have to add an excpetion in config/initializers/inflector.rb
like this one
ActiveSupport::Inflector.inflections do |inflect|
inflect.uncountable %w(faq)
end
It add an exception to pluralize and inflector rules of rails
As you have mentioned in routes resources :faq , it has not generate the routes admin_faqs_path but in the form_for by default it is searching for the admin_faqs_path. So we need to override it. Please change the code to
<%= form_for([:admin, #faq], :url => admin_faq_index_path, :method => :post) do |f| %>

What is wrong for my form for this shallow route?

here is my route
resources :games do
resources :message_templates, :shallow => true
my rake routes is like this
game_message_templates GET /games/:game_id/message_templates(.:format) message_templates#index
POST /games/:game_id/message_templates(.:format) message_templates#create
new_game_message_template GET /games/:game_id/message_templates/new(.:format) message_templates#new
edit_message_template GET /message_templates/:id/edit(.:format) message_templates#edit
message_template GET /message_templates/:id(.:format) message_templates#show
PUT /message_templates/:id(.:format) message_templates#update
DELETE /message_templates/:id(.:format) message_templates#destroy
and my _form.erb, looks like this
<% form_for(#message_template) do |f| %>
but I get this error
undefined method `message_templates_path'
It looks like you're creating a new message template for a given game in which case you need to provide the route with the associated game. If it were an existing message template the path would be message_template_path rather than message_templates_path.
Say:
<% form_for([#game, #message_template]) do |f| %>

Routing / in Rails

I'm writing a simple Rails app with one main controller and I want to map /(:action(:id)) to this controller (basically remove the controller prefix at the beginning), but still have the path helpers I get by using map.resources.
I tried map.root :controller => 'notes', but I get an error:
undefined method `note_path' for #<ActionView::Base:0x102038b50>
where I use the link_to_unless_current function in my view.
Edit: Here is the code in index.html.erb that gives the error.
<% for note in category.notes %>
<h3><%= link_to_unless_current h(numbered_title note), note %></h3>
<% end %>
UPDATE: I don't know how I came to this question, but author just pointed out that this is 3 years old, which I totally missed. I will leave this answer if somebody needs that behaviour in rails 3. In rails 2 it is not valid...
Route root will not work with whole controller as this has to point on specific action.
First parameter of resources will be used to determine path (normally it would be /notes) and at the same time to create helpers like notes_path. What you want to do is set this to '/', but also add :as option to give proper helpers names. So finally it should look like:
resources '/', controller: :notes, as: :notes
Also quite important thing to notice, if you want to use any other resources, you should put them above notes route. Otherwise rails will recognize resources name as id of notes action show.
Example:
resources '/', controller: :notes, as: :notes
resources :comments
Going to /comments will try to find note with id 'comments'.
resources :comments
resources '/', controller: :notes, as: :notes
Opening /comments will go to comments_controller#index.

Resources