link_to a form in ruby - ruby-on-rails

I want to use the link to function to point to a form.
i.e <%= link_to 'Reports', '/reports/index.html.erb' %>
But this gives me a error saying no route matches '/reports/index.html.erb.
Thanks,
Ramya.

Rails doesn't like having the document format in the URL unless it's necessary (like when one action can handle multiple request formats). If you have reports/index.html.erb, the route to it would look like one of these:
match 'reports' => 'reports#index' #=> 'yourdomain.com/reports'
match 'reports/index' => 'reports#index' #=> 'yourdomain.com/reports/index
Then your link would be:
<%= link_to 'Reports', 'reports' %>
or
<%= link_to 'Reports', 'reports/index' %>
If you really wanted to have the .html, you could probably do it like this:
match 'reports/index.html' => 'reports#index' #=> 'yourdomain.com/reports/index.html
or
match 'reports/index.:format' => 'reports#index' #=> 'yourdomain.com/reports/index.html
But the .html is meaningless in the first case and unnecessary in the second. I don't recommend doing it this way, as it's not standard Rails practice.
I highly recommend you read this tutorial on Routing, at least the first few sections, before you move forward. It's an absolutely essential part of Rails, and if you don't understand how it works, you will never be a productive Rails programmer.

The link should point to the form from the server's point of view. Try <%= link_to 'Reports', '/reports/index.html' %> (without the '.erb')
Make sure that your routes really define that url. I guess it may be '/reports/' instead of '/reports/index.html', but YMMV.
Consult the output of command rake routes to see what routes are defined.

Related

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.

Link_to efficiency without fetching record

In my Rails app there are experiment instances and each experiment has attachments, which are represented as binary blobs in the database and can be quite big. This question is about efficiency in coding a link_to show the attachment.
Originally I had this:
<%= link_to #experiment.attachment.file_name, #experiment.attachment %>
However I was told that the Rails app would be more efficient in rendering the page with
<%= link_to #experiment.attachment.file_name, {:controller => :attachments, :action => :show, :id => #experiment.attachment_id}, {:method => :get} if ! #experiment.attachment_id.nil? %>
The justification is that the first version fetches the attachment from the database, and the second one does not, making it is better, albeit longer and uglier. Is this true?
Both versions accomplish the same thing in directing the user to the show page for an attachment and I was under the impression the first is the default way to do a link_to a record show page.
Is there a way to shorthand the second piece of code to make it less terrible with code in the view?
Try using a rails route helper, use rake routes to view all your routes and then you can get something like this (don't forget to apped _path to route):
experiment_attachment_path(#experiment.attachment)
I would express this using the route path rather than using the ActiveRecord instance to load so the view can use its to_param method (which is what it is doing under the hood).
<%= link_to #experiment.attachment.file_name, attachment_path(#experiment.attachment_id) %>

What Ruby construct does the link_to method in Rails use?

Say I have this route:
match '/somepage' => "home#somepage"
I can then do this on a different page to link to "somepage":
<%= link_to "Some Page", somepage_path %>
I'm new to both Ruby and Rails, and I'm struggling to understand how exactly the "somepage_path" part works. It's not a string, it's not a symbol, is it a method call? If so, where does that method exist? Seems like I'm missing something obvious...
On initialization all paths are generated according to the routes.rb definitions.
If you want to customize the routes names you can use
match '/somepage' => "home#somepage", :as => "foobar"
Later used as
<%= link_to "Some Page", foobar_path %>
Hope that clears some stuff up about custom routing :)
Link magic is all handled by ActionDispatch::URL::UrlFor, see ActionDispatch::URL::UrlFor

Passing id in form_for action

I have a form to update an attribute of a model - I don't want it to go to the standard update action I want it to go to a different action.
<% for car in #cars %>
<%= form_for car, :url => { :action => "custom_action/#{car.id}" } do |f| -%>
This is giving the following error -
No route matches {:action=>"custom_action/1", :controller=>"cars"}
However if I visit the url - custom_action/1 - I don't get the routing error.
Any idea why I can't do this?
In addition to what Frederick Cheung said about GET vs POST vs PUT, I think your code might be wrong in general.
To do exactly what you want, try:
form_for car, :url => {:action => "custom_action", :id => car, :controller => "cars"} do |f|
I don't think this is a good idea, and will probably cause you pain. I suggest taking a look at the Ruby on Rails Routing Guide, to understand how to do this properly. (Routing is a topic where I always have to consult the manual.)
With correct routes your code should look something like this:
form_for car, custom_action_car_path(car) do |f|
Which will be easier to change in the future if/when you refactor your app.
If you go to the url by typing it into the url bar, you're making a GET request, whereas forms emit POST requests by default, and in this case would probably emit a PUT request (since you're acting on an existing record).
It sounds like your route is only routing GET requests. Given that you say your custom action does update the record, it sounds like you should update your routes to accept PUT requests instead.

How to get link_to in Rails output an SEO friendly url?

My link_to tag is:
<%= link_to("My test title",{:controller=>"search", :action=>"for-sale", :id=> listing.id, :title => listing.title, :search_term => search_term}) %>
and produces this ugly URL:
http://mysite.com/search/for-sale/12345?title=premium+ad+%2B+photo+%5Btest%5D
How can I get link_to to generate:
http://mysite.com/search/for-sale/listing-title/search-term/12345
Been trying this a few different ways and cannot find much online, really appreciate any help!
Tahe a look at this
add this in your config/routes.rb
map.connect ':controller/:action/:title/search_item/:id', :controller=>'search', :action=>'for_sale'
restart your server and check.
Hope that helps :)
You need to change the URL structure in routes.rb to match what you want the URL to look like, and parse the parameters accordingly in your controller method's args.

Resources