label
label(object_name, method, text = nil, options = {})Returns a label tag tailored for labelling an input field for a specified attribute (identified by method) on an object assigned to the template (identified by object). The text of label will default to the attribute name unless a translation is found in the current I18n locale (through views.labels.<modelname>.<attribute>) or you specify it explicitly. Additional options on the label tag can be passed as a hash with options. These options will be tagged onto the HTML as an HTML element attribute as in the example shown, except for the :value option, which is designed to target labels for radio_button tags (where the value is used in the ID of the input tag).
Examples
label(:post, :title) # => <label for="post_title">Title</label> You can localize your labels based on model and attribute names. For example you can define the following in your locale (e.g. en.yml) views: labels: post: body: "Write your entire text here" Which then will result in label(:post, :body) # => <label for="post_body">Write your entire text here</label> Localization can also be based purely on the translation of the attribute-name like this: activerecord: attribute: post: cost: "Total cost" label(:post, :cost) # => <label for="post_cost">Total cost</label> label(:post, :title, "A short title") # => <label for="post_title">A short title</label> label(:post, :title, "A short title", :class => "title_label") # => <label for="post_title" class="title_label">A short title</label> label(:post, :privacy, "Public Post", :value => "public") # => <label for="post_privacy_public">Public Post</label>
5Notes
Translations of label method
The label method won't use your translated attribute names - which seems like big disadvantage of this method.
For a quick workaround, try using this in a helper: def label(object_name, method, text = nil, options = {}) text ||= object_name.classify.constantize.human_attribute_name(method.to_s) ActionView::Helpers::InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options) end
I didn't properly test this, but it seems to work.
label DOES translate
Maybe it used to not translate but I know it does as of 2.3.8. It is first lookup on the key:
helpers.label.<object_name>.<method_name>
If that doesn't return anything it will use the +human_attribute_name+ method on ActiveRecord::Base to translated which uses:
activerecord.attributes.<object>.<attribute>
I generally use both of these keys even when I don't want to translate but just to have a single place where all my adjusted labels are stored.
If any form will need to use the same adjustment given the same object and attribute then I put in on the +activerecord+ key. If the adjustment is form specific then I put it on the +helpers+ key. Here is an example from real working code:
en:
activerecord:
attributes:
"content/rich_text":
name: Page name
helpers:
label:
content_rich_text:
testimonial_enabled: Enabled
Note that my AR object is a namespaced object (Content::RichText). In the +activerecord+ key I need to change this to +content/rich_text+ so if can find the correct key and put it in quotes to make it valid YAML. At the helper level on the other hand the namespace simply becomes an +_+.
Unusual block calling
It is important to note that the block form of this method is unlike any other block form in Rails. You would expect this to work:
<%= f.label :terms_and_conditions do %>
Accept <%= link_to_page 'Terms and Conditions' %>
<% end %>
But doing this ends up messing up the form (I ended up with the form repeating itself). Instead you need to do:
<%= f.label :terms_and_conditions do
'Accept ' + link_to_page('Terms and Conditions')
end %>
Which is really only mildly better than not using the block form:
<%= f.label :terms_and_conditions,
'Accept ' + link_to_page('Terms and Conditions') %>
You are actually better of using capture if your code lends itself to the first non-working form:
<%= f.label :terms_and_conditions, (capture do %>
Accept <%= link_to_page 'Terms and Conditions' %>
<% end) %>
Or if you prefer brackets to parenthesis you can do:
<%= f.label :terms_and_conditions, capture { %>
Accept <%= link_to_page 'Terms and Conditions' %>
<% } %>
customizing text when using label in a form
Instead of the default text Email you can change it to "Primary Email" like this: f.label :email, "Primary Email"
Save yourself a little typing
We often have a form with a select box that selects a model association. So for example to select a colour, when there is an associated Colour model, a select box will typically select :colour_id.
In this case, ActionView automatically humanizes :colour_id to produce "Colour" as the label text.