17

It's obvious from the documentation (and google) how to generate a link with a segment e.g. podcast/5#comments. You just pass a value for :anchor to link_to.

My concern is about the much simpler task of generating the <a name="comments">Comments</a> tag i.e. the destination of the first link.

I've tried the following, and although they seemed to work, the markup was not what I expected:

link_to "Comments", :name => "comments"
link_to "Comments", :anchor => "comments"

I think I'm missing something obvious. Thanks.

Joe Flynn
  • 6,908
  • 6
  • 31
  • 44
  • Sorry for not understanding what you *clearly* wrote! My bad! Glad you got the answer you needed. I removed mine so not to confuse anyone :) – Doug Neiner Jan 19 '10 at 15:52

3 Answers3

54

You are getting confused by Ruby's syntactic sugar (which Rails uses profusely). Let me explain this briefly before answering your question.

When a ruby function takes a single parameter that is a hash:

def foo(options)
  #options is a hash with parameters inside
end

You can 'forget' to put the parenthesis/brackets, and call it like this:

foo :param => value, :param2 => value

Ruby will fill out the blanks and understand that what you are trying to accomplish is this:

foo({:param => value, :param2 => value})

Now, to your question: link_to takes two optional hashes - one is called options and the other html_options. You can imagine it defined like this (this is an approximation, it is much more complex)

def link_to(name, options, html_options)
...
end

Now, if you invoke it this way:

link_to 'Comments', :name => 'Comments'

Ruby will get a little confused. It will try to "fill out the blanks" for you, but incorrectly:

link_to('Comments', {:name => 'Comments'}, {}) # incorrect

It will think that name => 'Comments' part belongs to options, not to html_options!

You have to help ruby by filling up the blanks yourself. Put all the parenthesis in place and it will behave as expected:

link_to('Comments', {}, {:name => 'Comments'}) # correct

You can actually remove the last set of brackets if you want:

link_to("Comments", {}, :name => "comments") # also correct

In order to use html_options, you must leave the first set of brackets, though. For example, you will need to do this for a link with confirmation message and name:

link_to("Comments", {:confirm => 'Sure?'}, :name => "comments")

Other rails helpers have a similar construction (i.e. form_for, collection_select) so you should learn this technique. In doubt, just add all the parenthesis.

kikito
  • 51,734
  • 32
  • 149
  • 189
14

If you want to go through rails, I suggest content_tag (docs).

Example:

content_tag(:a, 'Comments', :name => 'comments')
notapatch
  • 6,569
  • 6
  • 41
  • 45
theIV
  • 25,434
  • 5
  • 54
  • 58
  • 1
    Thanks, I think that's what I was looking for. It occurs to me now that in haml, it'll just take `%a{:name => "comments"} Comments` to make that link. I guess I just expected not to be hard coding links in rails. – Joe Flynn Jan 19 '10 at 15:41
  • Sometimes it's nicer to just throw a tag in, but if you are erb'ing and don't want to break out of ruby, this is nice, too :) – theIV Jan 20 '10 at 16:06
  • I still like this answer, but egarcia's is what I was looking for. – Joe Flynn Jan 20 '10 at 18:56
0
<%= link_to('new button', action: 'login' , class: "text-center") %>

created an anchor tag for login.html i.g

<a href="login.html" class = "text-center"> new button </a>

and for

<a href="admin/login.html" class = "text-center"> new button </a>

use

<%= link_to('new button', controller: 'admin',
    action: 'login' , class: "text-center") %>