Rails nested routes with link_to - ruby-on-rails

I'm trying to use a link_to from my view into a nested route and I am sure I just have my syntax incorrect. The basic flow of my app is there is a summary that has many feeds which then have many log lines. its a very basic report
My route is
resources :perfsums, :only => [:index] do
resources :perffeedresults, :only => [:index] do
resources :loglines, :only => [:index] do
end
end
end
Here is how the rake routes looks for that
perfsum_perffeedresult_loglines_path GET /perfsums/:perfsum_id/perffeedresults/:perffeedresult_id/loglines(.:format) loglines#index
In my view I have a link to I want to link from the feed class to log lines using the feed ID. Should be very simple. My link to looks like this
<td> <%= link_to c.id, perfsum_perffeedresult_loglines(c) %> </td>
Going directly to the page by hand works as the link below shows I just can't get there form that link to
http://localhost:3000/perfsums/19/perffeedresults/143/loglines
When I try to run with that link_to I get. I have tried a few different options here none have worked.
undefined method `perfsum_perffeedresult_loglines' for #<#<Class:0x007fad31b60dd8>:0x007fad386d86b0>
I do use a link_to to go from the summary to the feeds page fine its just that extra bit of nesting t hats throwing me off I think.

First of all, it's a perfsum_perffeedresult_loglines_path, you missed _path, which should be added to get a path. And you need to pass two params, look at the path:
/perfsums/:perfsum_id/perffeedresults/:perffeedresult_id/loglines
You need to pass a perfsum and a perffeedresult:
<td> <%= link_to c.id, perfsum_perffeedresult_loglines_path(perfsum, perffeedresult) %> </td>

Related

Rails 5 route, url issue

I'm having an issue trying to get a link_to working after changing routes on my app. This may be a simple one but I honestly cannot see just linking to link_to with the object name will not work as previously did before the route changed.
Background: I'm using friendly_id gem (not sure if i still need this after making changes to the url manually).
I'm also using Ancestory gem in there too.
On the front facing app. I've a listings resource that is only used for index and show. See below routes and also previous working route.
# Front facing resources
scope "/:category_name/:category_id" do
resources :listings, only: [:show], path: '/:title'
end
resources :listings, only: [:index]
before (working fine)
# Front facing resources
resources :listings, only: [:index, :show]
resources :auctions, only: [:index, :show]
I've been successful making my url show a result of:
listing GET /:category_name/:category_id/:title/:id(.:format) listings#show
result:
http://localhost:3000/listings/helicopter/test-one/4
This will do for now. I'm still trying to figure the end url. So I can create the listing and view it my manually typing the url into the browser.
The error occurs when I'm viewing the Index page of the listings and I have a link_to
current code:
<%= link_to listing.title, listing %>
Error:
No route matches {:action=>"show", :controller=>"listings"}, missing required keys: [:category_id, :category_name, :id, :title]
What way do I go about adding these required keys to the link_to helper? I've tried lots of ways but not far. I presumed changing just the show route would not have messed too much with any previous controller methods and that the listing would still be found by id.
Any direction would be great. Thanks a million.
*** UPDATE ****
Ok so before sending the above I had a closer look and got it working however I'm asking is there a cleaner way to do this? It just doesn't look very "The Rails way". My end goal is to have a long SEO friendly link that contains category and possibly subcategories.
Working code:
<%= link_to listing.title, listing_path(category_name: "listings", category_id: listing.category.name, title: listing.title.parameterize, id: listing.id) %>
Result:
http://localhost:3000/listings/Aircraft/twin-piston-jet/1
Thoughts please???
You could use helpers for that https://api.rubyonrails.org/classes/ActionController/Helpers.html
app/helpers/listing_helper.rb
module ListingHelper
def listing_route(listing, category_name = "Listings")
listing_path(category_name: listing, category_name: listing.category.name, title: listing.title.parameterize, id: listing.id)
end
end
On your views
<%= link_to listing.title, listing_route(listing) %>

rails 5 adding menu to dashing-rails layout

What is the best way to be able to add a similar layout to dashing dashboard, like we have in out application. I tried to add the same materalize layout I use throughout my application and it seems to be breaking on each link_to which I have in my main layout.
example of a broken link:
undefined local variable or method `edit_user_registration_path'
adding routes file portion as an example.
Rails.application.routes.draw do
mount Dashing::Engine, at: Dashing.config.engine_path
resources :bills
resources :unit_types, :except => [:show]
end
so if I add link_to bills_path it results in error.
The answer is provided here.
Link
all that is needed is a link_to with main_app before the actual route.
<%= link_to "About", main_app.about_path %>

Better routes in rails with params

I've been working on a movie application in Rails. I have a controller/view for the actor. When passing params to the actors controller i want the URL to be pretty. Now it looks like this: http://localhost:3000/actors/show?actor=Hayley+Atwell and i want it to look like /actors/show/Hayley+Atwell or /actors/Hayley+Atwell.
How do i do this? My link in the movies view is:
<%= link_to a.name, {:controller => 'actors', :action => 'show', :actor => a.name}, :class => "label label-default" %>
My routes.rb is now like this:
get 'actors/show'
I recommend you use friendly_id gem. It perfectly satisfies your needs!
https://github.com/norman/friendly_id
You can use the following in your ./config/route.rb file:
get '/actors/:actor', to: 'actors#show'
I'll give a series of refactoring advice as follow:
Try to make use of the actor's id instead of the name
Change the route to: get '/actors/show/:id', to: 'actors#show'
Then, you can now change the link in your view to something like:
<%= link_to a.name, {:controller => 'actors', :action => 'show', :id => a.id}, :class => "label label-default" %>
Note: the : part in the :id of your route means that this could be interchanged to anything, and whatever comes in that place will be interpreted as the id. So, in /actors/show/7, the id of the actor is 7, you can now find the actor with this id in your controller action, and do anything you want with it.
If I'm right than you try to create RESTful routes anyway.
So I would recommend you to use the Rails' resources method in your routes:
Rails.application.routes.draw do
resources :actors # If you want only the :show action than add:
# , only: [:show]
end
This automatically creates the proper routes for you.
To get the names into the URL you should use the friendly_id gem. It has a great community and is very well tested.

Action Controller error. Url Generation error. No route matches

I'm working through the "Ruby on rails 3 essential training" on lynda.com and am having an issue while generating my server. So far I have a subjects_controller.rb, linked to my views folder, to the file list.html.erb. My error when trying to start the server is:
No route matches {:action=>"show", :controller="subjects", :id=>1}
In my list.html.erb file I have written the code:
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
<%= link_to("Edit", '#', :class => 'action edit') %>
<%= link_to("Delete", '#', :class => 'action delete') %>
</td>
My subjects_controller.rb looks like:
class SubjectsController < ApplicationController
def list
#subjects = Subject.order("subjects.position ASC")
end
end
I have double checked to make sure I have everything written the same as the instructor but there seems to be a missing link. Any ideas? If I totally cut out the action:
<%= link_to("Show", {:action => 'show', :id => subject.id}, :class => 'action show') %>
Then the server starts up. There must be a problem here but I'm not sure what it is. Also when the instructor inputs link_to on his text editor, the txt turns a different color and mine does not. Same thing with his "#" instance variable. Mine doesn't change color. Not sure if this means anything either. Thanks for any input!
Here is my config/routes.rb file:
Rails.application.routes.draw do
root :to => "demo#index"
get 'demo/index'
get 'demo/hello'
get 'demo/other_hello'
get 'subjects/list'
end
Short version: The error message is telling you exactly what is wrong. You have no route that matches, because while your action is named list, your link specifies :action => 'show'.
Longer version: The second argument to the link_to helper is supposed to tell Rails what URL to generate for the link, usually by specifying one of your routes by name, but sometimes (as in this case), by specifying the action (and optionally the controller). You're specifying the action show. The subjects controller is implied. Therefore, Rails is trying to find a route (in the ones defined in your routes.rb) that GETs the SubjectsController#show action. However, as you can see from your routes.rb, you only define one route on the SubjectsController, and that's list.
If you're ever confused about what routes you have or what their names are, you can use the rake routes task to list them all out in a nice readable format.
Edit to respond to followup question:
The instructor is telling me that when you generate a controller and
action that its supposed to add a route to the routes.rb folder. This
worked for me earlier but when creating these actions that I'm having
trouble with now, it didn't generate anything in the routes.rb folder.
Do you know why that is?
When your instructor says 'generate', they probably mean 'use the rails generate command'. When you use the generator to create a controller and specify the actions in it, the it will also add those actions to the routes file.
If, on the other hand, you write the action into an existing controller (including using the generator for the controller but not specifying actions), or create the controller file yourself, you'll have to update the routes file manually. If you are using the generator and specifying actions and aren't getting updated routes, I'm not sure what's going on.
Personally, I prefer to write my routes by hand anyway - the generator often doesn't get them exactly right.

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