Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove RecordTagHelper #18411

Merged
merged 1 commit into from Feb 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions actionview/CHANGELOG.md
@@ -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.
Expand Down
2 changes: 2 additions & 0 deletions actionview/lib/action_view/helpers/form_helper.rb
Expand Up @@ -4,6 +4,7 @@
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'
Expand Down Expand Up @@ -110,6 +111,7 @@ module FormHelper
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.
Expand Down
111 changes: 12 additions & 99 deletions actionview/lib/action_view/helpers/record_tag_helper.rb
@@ -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
90 changes: 3 additions & 87 deletions actionview/test/template/record_tag_helper_test.rb
Expand Up @@ -24,94 +24,10 @@ def setup
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can keep only 1 test for each method, should be enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I figured that would probably be enough, but I wanted to cover all the cases. I'll slim this down.


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
77 changes: 0 additions & 77 deletions guides/source/action_view_overview.md
Expand Up @@ -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.
Expand Down