Merge pull request #18411 from todd/extract_record_tag_helper

Remove RecordTagHelper
This commit is contained in:
Rafael Mendonça França 2015-02-18 19:19:48 -02:00
commit 4ffe46f5fe
5 changed files with 22 additions and 263 deletions

View File

@ -1,3 +1,8 @@
* Extracted `ActionView::Helpers::RecordTagHelper` to external gem
(`record_tag_helper`) and added removal notices.
*Todd Bealmear*
* Allow to pass a string value to `size` option in `image_tag` and `video_tag`.
This makes the behavior more consistent with `width` or `height` options.

View File

@ -4,6 +4,7 @@ require 'action_view/helpers/tag_helper'
require 'action_view/helpers/form_tag_helper'
require 'action_view/helpers/active_model_helper'
require 'action_view/model_naming'
require 'action_view/record_identifier'
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/output_safety'
@ -110,6 +111,7 @@ module ActionView
include FormTagHelper
include UrlHelper
include ModelNaming
include RecordIdentifier
# Creates a form that allows the user to create or update the attributes
# of a specific model object.

View File

@ -1,108 +1,21 @@
require 'action_view/record_identifier'
module ActionView
# = Action View Record Tag Helpers
module Helpers
module RecordTagHelper
include ActionView::RecordIdentifier
# Produces a wrapper DIV element with id and class parameters that
# relate to the specified Active Record object. Usage example:
#
# <%= div_for(@person, class: "foo") do %>
# <%= @person.name %>
# <% end %>
#
# produces:
#
# <div id="person_123" class="person foo"> Joe Bloggs </div>
#
# You can also pass an array of Active Record objects, which will then
# get iterated over and yield each record as an argument for the block.
# For example:
#
# <%= div_for(@people, class: "foo") do |person| %>
# <%= person.name %>
# <% end %>
#
# produces:
#
# <div id="person_123" class="person foo"> Joe Bloggs </div>
# <div id="person_124" class="person foo"> Jane Bloggs </div>
#
def div_for(record, *args, &block)
content_tag_for(:div, record, *args, &block)
def div_for(*)
raise NoMethodError, "The `div_for` method has been removed from " \
"Rails. To continue using it, add the `record_tag_helper` gem to " \
"your Gemfile:\n" \
" gem 'record_tag_helper', '~> 1.0'\n" \
"Consult the Rails upgrade guide for details."
end
# content_tag_for creates an HTML element with id and class parameters
# that relate to the specified Active Record object. For example:
#
# <%= content_tag_for(:tr, @person) do %>
# <td><%= @person.first_name %></td>
# <td><%= @person.last_name %></td>
# <% end %>
#
# would produce the following HTML (assuming @person is an instance of
# a Person object, with an id value of 123):
#
# <tr id="person_123" class="person">....</tr>
#
# If you require the HTML id attribute to have a prefix, you can specify it:
#
# <%= content_tag_for(:tr, @person, :foo) do %> ...
#
# produces:
#
# <tr id="foo_person_123" class="person">...
#
# You can also pass an array of objects which this method will loop through
# and yield the current object to the supplied block, reducing the need for
# having to iterate through the object (using <tt>each</tt>) beforehand.
# For example (assuming @people is an array of Person objects):
#
# <%= content_tag_for(:tr, @people) do |person| %>
# <td><%= person.first_name %></td>
# <td><%= person.last_name %></td>
# <% end %>
#
# produces:
#
# <tr id="person_123" class="person">...</tr>
# <tr id="person_124" class="person">...</tr>
#
# content_tag_for also accepts a hash of options, which will be converted to
# additional HTML attributes. If you specify a <tt>:class</tt> value, it will be combined
# with the default class name for your object. For example:
#
# <%= content_tag_for(:li, @person, class: "bar") %>...
#
# produces:
#
# <li id="person_123" class="person bar">...
#
def content_tag_for(tag_name, single_or_multiple_records, prefix = nil, options = nil, &block)
options, prefix = prefix, nil if prefix.is_a?(Hash)
Array(single_or_multiple_records).map do |single_record|
content_tag_for_single_record(tag_name, single_record, prefix, options, &block)
end.join("\n").html_safe
def content_tag_for(*)
raise NoMethodError, "The `content_tag_for` method has been removed from " \
"Rails. To continue using it, add the `record_tag_helper` gem to " \
"your Gemfile:\n" \
" gem 'record_tag_helper', '~> 1.0'\n" \
"Consult the Rails upgrade guide for details."
end
private
# Called by <tt>content_tag_for</tt> internally to render a content tag
# for each record.
def content_tag_for_single_record(tag_name, record, prefix, options, &block)
options = options ? options.dup : {}
options[:class] = [ dom_class(record, prefix), options[:class] ].compact
options[:id] = dom_id(record, prefix)
if block_given?
content_tag(tag_name, capture(record, &block), options)
else
content_tag(tag_name, "", options)
end
end
end
end
end

View File

@ -24,94 +24,10 @@ class RecordTagHelperTest < ActionView::TestCase
end
def test_content_tag_for
expected = %(<li class="record_tag_post" id="record_tag_post_45"></li>)
actual = content_tag_for(:li, @post)
assert_dom_equal expected, actual
assert_raises(NoMethodError) { content_tag_for(:li, @post) }
end
def test_content_tag_for_prefix
expected = %(<ul class="archived_record_tag_post" id="archived_record_tag_post_45"></ul>)
actual = content_tag_for(:ul, @post, :archived)
assert_dom_equal expected, actual
end
def test_content_tag_for_with_extra_html_options
expected = %(<tr class="record_tag_post special" id="record_tag_post_45" style='background-color: #f0f0f0'></tr>)
actual = content_tag_for(:tr, @post, class: "special", style: "background-color: #f0f0f0")
assert_dom_equal expected, actual
end
def test_content_tag_for_with_array_css_class
expected = %(<tr class="record_tag_post special odd" id="record_tag_post_45"></tr>)
actual = content_tag_for(:tr, @post, class: ["special", "odd"])
assert_dom_equal expected, actual
end
def test_content_tag_for_with_prefix_and_extra_html_options
expected = %(<tr class="archived_record_tag_post special" id="archived_record_tag_post_45" style='background-color: #f0f0f0'></tr>)
actual = content_tag_for(:tr, @post, :archived, class: "special", style: "background-color: #f0f0f0")
assert_dom_equal expected, actual
end
def test_block_not_in_erb_multiple_calls
expected = %(<div class="record_tag_post special" id="record_tag_post_45">What a wonderful world!</div>)
actual = div_for(@post, class: "special") { @post.body }
assert_dom_equal expected, actual
actual = div_for(@post, class: "special") { @post.body }
assert_dom_equal expected, actual
end
def test_block_works_with_content_tag_for_in_erb
expected = %(<tr class="record_tag_post" id="record_tag_post_45">What a wonderful world!</tr>)
actual = render_erb("<%= content_tag_for(:tr, @post) do %><%= @post.body %><% end %>")
assert_dom_equal expected, actual
end
def test_div_for_in_erb
expected = %(<div class="record_tag_post special" id="record_tag_post_45">What a wonderful world!</div>)
actual = render_erb("<%= div_for(@post, class: 'special') do %><%= @post.body %><% end %>")
assert_dom_equal expected, actual
end
def test_content_tag_for_collection
post_1 = RecordTagPost.new { |post| post.id = 101; post.body = "Hello!" }
post_2 = RecordTagPost.new { |post| post.id = 102; post.body = "World!" }
expected = %(<li class="record_tag_post" id="record_tag_post_101">Hello!</li>\n<li class="record_tag_post" id="record_tag_post_102">World!</li>)
actual = content_tag_for(:li, [post_1, post_2]) { |post| post.body }
assert_dom_equal expected, actual
end
def test_content_tag_for_collection_without_given_block
post_1 = RecordTagPost.new.tap { |post| post.id = 101; post.body = "Hello!" }
post_2 = RecordTagPost.new.tap { |post| post.id = 102; post.body = "World!" }
expected = %(<li class="record_tag_post" id="record_tag_post_101"></li>\n<li class="record_tag_post" id="record_tag_post_102"></li>)
actual = content_tag_for(:li, [post_1, post_2])
assert_dom_equal expected, actual
end
def test_div_for_collection
post_1 = RecordTagPost.new { |post| post.id = 101; post.body = "Hello!" }
post_2 = RecordTagPost.new { |post| post.id = 102; post.body = "World!" }
expected = %(<div class="record_tag_post" id="record_tag_post_101">Hello!</div>\n<div class="record_tag_post" id="record_tag_post_102">World!</div>)
actual = div_for([post_1, post_2]) { |post| post.body }
assert_dom_equal expected, actual
end
def test_content_tag_for_single_record_is_html_safe
result = div_for(@post, class: "special") { @post.body }
assert result.html_safe?
end
def test_content_tag_for_collection_is_html_safe
post_1 = RecordTagPost.new { |post| post.id = 101; post.body = "Hello!" }
post_2 = RecordTagPost.new { |post| post.id = 102; post.body = "World!" }
result = content_tag_for(:li, [post_1, post_2]) { |post| post.body }
assert result.html_safe?
end
def test_content_tag_for_does_not_change_options_hash
options = { class: "important" }
content_tag_for(:li, @post, options)
assert_equal({ class: "important" }, options)
def test_div_for
assert_raises(NoMethodError) { div_for(@post, class: "special") }
end
end

View File

@ -365,83 +365,6 @@ WIP: Not all the helpers are listed here. For a full list see the [API documenta
The following is only a brief overview summary of the helpers available in Action View. It's recommended that you review the [API Documentation](http://api.rubyonrails.org/classes/ActionView/Helpers.html), which covers all of the helpers in more detail, but this should serve as a good starting point.
### RecordTagHelper
This module provides methods for generating container tags, such as `div`, for your record. This is the recommended way of creating a container for render your Active Record object, as it adds an appropriate class and id attributes to that container. You can then refer to those containers easily by following the convention, instead of having to think about which class or id attribute you should use.
#### content_tag_for
Renders a container tag that relates to your Active Record Object.
For example, given `@article` is the object of `Article` class, you can do:
```html+erb
<%= content_tag_for(:tr, @article) do %>
<td><%= @article.title %></td>
<% end %>
```
This will generate this HTML output:
```html
<tr id="article_1234" class="article">
<td>Hello World!</td>
</tr>
```
You can also supply HTML attributes as an additional option hash. For example:
```html+erb
<%= content_tag_for(:tr, @article, class: "frontpage") do %>
<td><%= @article.title %></td>
<% end %>
```
Will generate this HTML output:
```html
<tr id="article_1234" class="article frontpage">
<td>Hello World!</td>
</tr>
```
You can pass a collection of Active Record objects. This method will loop through your objects and create a container for each of them. For example, given `@articles` is an array of two `Article` objects:
```html+erb
<%= content_tag_for(:tr, @articles) do |article| %>
<td><%= article.title %></td>
<% end %>
```
Will generate this HTML output:
```html
<tr id="article_1234" class="article">
<td>Hello World!</td>
</tr>
<tr id="article_1235" class="article">
<td>Ruby on Rails Rocks!</td>
</tr>
```
#### div_for
This is actually a convenient method which calls `content_tag_for` internally with `:div` as the tag name. You can pass either an Active Record object or a collection of objects. For example:
```html+erb
<%= div_for(@article, class: "frontpage") do %>
<td><%= @article.title %></td>
<% end %>
```
Will generate this HTML output:
```html
<div id="article_1234" class="article frontpage">
<td>Hello World!</td>
</div>
```
### AssetTagHelper
This module provides methods for generating HTML that links views to assets such as images, JavaScript files, stylesheets, and feeds.