cells 3.8.8 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.travis.yml +5 -2
- data/CHANGES.textile +23 -15
- data/Gemfile +1 -1
- data/README.md +412 -0
- data/Rakefile +2 -2
- data/cells.gemspec +5 -6
- data/gemfiles/Gemfile.rails3-0 +2 -2
- data/gemfiles/Gemfile.rails3-1 +1 -1
- data/gemfiles/Gemfile.rails3-2 +1 -2
- data/gemfiles/Gemfile.rails4-0 +7 -0
- data/lib/cell.rb +27 -0
- data/lib/cell/base.rb +31 -18
- data/lib/cell/builder.rb +11 -10
- data/lib/cell/dsl.rb +7 -0
- data/lib/cell/rack.rb +5 -9
- data/lib/cell/rails.rb +19 -11
- data/lib/cell/rails/view_model.rb +115 -0
- data/lib/cell/rails3_0_strategy.rb +1 -1
- data/lib/cell/rails3_1_strategy.rb +1 -1
- data/lib/cell/rails4_0_strategy.rb +1 -2
- data/lib/cell/test_case.rb +11 -11
- data/lib/cells.rb +4 -3
- data/lib/cells/rails.rb +16 -3
- data/lib/cells/version.rb +1 -1
- data/test/app/cells/bassist_cell.rb +9 -1
- data/test/app/cells/rails_helper_api_test/bassist/edit.html.erb +3 -3
- data/test/app/cells/song/dashboard.haml +7 -0
- data/test/app/cells/song/details.html.haml +1 -0
- data/test/app/cells/song/info.html.haml +1 -0
- data/test/app/cells/song/lyrics.html.haml +6 -0
- data/test/app/cells/song/plays.haml +1 -0
- data/test/app/cells/song/show.html.haml +3 -0
- data/test/app/cells/song/title.html.haml +1 -0
- data/test/app/cells/view_model_test/comments/show.haml +7 -0
- data/test/cell_module_test.rb +39 -41
- data/test/cell_test.rb +28 -0
- data/test/dummy/app/views/musician/featured_with_block.html.erb +1 -1
- data/test/dummy/app/views/musician/title.erb +1 -0
- data/test/dummy/config/routes.rb +1 -0
- data/test/helper_test.rb +13 -10
- data/test/rails/caching_test.rb +75 -73
- data/test/rails/cells_test.rb +25 -23
- data/test/rails/integration_test.rb +80 -61
- data/test/rails/view_model_test.rb +119 -0
- data/test/rails_helper_api_test.rb +11 -13
- metadata +41 -61
- data/README.rdoc +0 -279
- data/about.yml +0 -7
- data/test/app/cells/producer/capture.html.erb +0 -1
- data/test/app/cells/producer/content_for.html.erb +0 -2
- data/test/rails/capture_test.rb +0 -70
data/Rakefile
CHANGED
|
@@ -3,11 +3,11 @@ Bundler::GemHelper.install_tasks
|
|
|
3
3
|
|
|
4
4
|
require 'rake/testtask'
|
|
5
5
|
|
|
6
|
-
desc '
|
|
6
|
+
desc 'Default: run unit tests.'
|
|
7
7
|
task :default => :test
|
|
8
8
|
|
|
9
9
|
Rake::TestTask.new(:test) do |test|
|
|
10
10
|
test.libs << 'test'
|
|
11
|
-
test.test_files = FileList['test/*_test.rb', 'test/rails/*_test.rb']
|
|
11
|
+
test.test_files = FileList['test/*_test.rb', 'test/rails/*_test.rb']
|
|
12
12
|
test.verbose = true
|
|
13
13
|
end
|
data/cells.gemspec
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
|
2
1
|
lib = File.expand_path('../lib/', __FILE__)
|
|
3
2
|
$:.unshift lib unless $:.include?(lib)
|
|
4
3
|
|
|
@@ -13,19 +12,19 @@ Gem::Specification.new do |s|
|
|
|
13
12
|
s.homepage = "http://cells.rubyforge.org"
|
|
14
13
|
s.summary = %q{View Components for Rails.}
|
|
15
14
|
s.description = %q{Cells are view components for Rails. They are lightweight controllers, can be rendered in views and thus provide an elegant and fast way for encapsulation and component-orientation.}
|
|
16
|
-
|
|
15
|
+
s.license = 'MIT'
|
|
16
|
+
|
|
17
17
|
s.files = `git ls-files`.split("\n")
|
|
18
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
s.add_dependency "actionpack", ">= 3.0"
|
|
23
23
|
s.add_dependency "railties", ">= 3.0"
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
s.add_development_dependency "rake"
|
|
26
26
|
s.add_development_dependency "haml"
|
|
27
27
|
s.add_development_dependency "slim"
|
|
28
|
-
s.add_development_dependency "simple_form"
|
|
29
28
|
s.add_development_dependency "tzinfo" # FIXME: why the hell do we need this for 3.1?
|
|
30
|
-
s.add_development_dependency "minitest", "
|
|
29
|
+
s.add_development_dependency "minitest", "~> 4.7.5"
|
|
31
30
|
end
|
data/gemfiles/Gemfile.rails3-0
CHANGED
data/gemfiles/Gemfile.rails3-1
CHANGED
data/gemfiles/Gemfile.rails3-2
CHANGED
data/lib/cell.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Cell
|
|
2
|
+
module OptionsConstructor
|
|
3
|
+
private
|
|
4
|
+
def process_args(options={})
|
|
5
|
+
if options.is_a?(Hash) # TODO: i don't like this too much.
|
|
6
|
+
process_options(options)
|
|
7
|
+
else
|
|
8
|
+
process_model(options)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
super # Base.
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# DISCUSS: have 2 classes for that?
|
|
15
|
+
|
|
16
|
+
def process_options(options)
|
|
17
|
+
options.each do |k, v|
|
|
18
|
+
instance_variable_set("@#{k}", v)
|
|
19
|
+
singleton_class.class_eval { attr_reader k }
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def process_model(model)
|
|
24
|
+
@model = model
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/cell/base.rb
CHANGED
|
@@ -2,40 +2,53 @@ require 'abstract_controller'
|
|
|
2
2
|
require 'cell/builder'
|
|
3
3
|
require 'cell/caching'
|
|
4
4
|
require 'cell/rendering'
|
|
5
|
+
require 'cell/dsl'
|
|
5
6
|
|
|
6
7
|
module Cell
|
|
7
8
|
def self.rails3_0?
|
|
8
9
|
::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR == 0
|
|
9
10
|
end
|
|
10
|
-
|
|
11
|
+
|
|
11
12
|
def self.rails3_1_or_more?
|
|
12
|
-
::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR >= 1
|
|
13
|
+
(::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR >= 1) or ::ActionPack::VERSION::MAJOR > 3
|
|
13
14
|
end
|
|
14
|
-
|
|
15
|
-
def self.rails3_2_or_more?
|
|
16
|
-
::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR >= 2
|
|
15
|
+
|
|
16
|
+
def self.rails3_2_or_more?
|
|
17
|
+
(::ActionPack::VERSION::MAJOR == 3 and ::ActionPack::VERSION::MINOR >= 2) or ::ActionPack::VERSION::MAJOR > 3
|
|
17
18
|
end
|
|
18
19
|
|
|
19
|
-
def self.rails4_0_or_more?
|
|
20
|
-
::ActionPack::VERSION::MAJOR == 4
|
|
20
|
+
def self.rails4_0_or_more?
|
|
21
|
+
(::ActionPack::VERSION::MAJOR == 4 and ::ActionPack::VERSION::MINOR >= 0) or ::ActionPack::VERSION::MAJOR > 4
|
|
21
22
|
end
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
|
|
24
25
|
class Base < AbstractController::Base
|
|
26
|
+
# TODO: deprecate Base in favour of Cell.
|
|
27
|
+
|
|
25
28
|
abstract!
|
|
26
29
|
DEFAULT_VIEW_PATHS = [File.join('app', 'cells')]
|
|
27
|
-
|
|
30
|
+
|
|
28
31
|
extend Builder
|
|
29
32
|
include AbstractController
|
|
30
33
|
include AbstractController::Rendering, Layouts, Helpers, Callbacks, Translation, Logger
|
|
31
|
-
|
|
34
|
+
|
|
32
35
|
require 'cell/rails3_0_strategy' if Cell.rails3_0?
|
|
33
36
|
require 'cell/rails3_1_strategy' if Cell.rails3_1_or_more?
|
|
34
37
|
require 'cell/rails4_0_strategy' if Cell.rails4_0_or_more?
|
|
35
38
|
include VersionStrategy
|
|
36
39
|
include Rendering
|
|
37
40
|
include Caching
|
|
38
|
-
|
|
41
|
+
include Cell::DSL
|
|
42
|
+
|
|
43
|
+
def initialize(*args)
|
|
44
|
+
super() # AbC::Base.
|
|
45
|
+
process_args(*args)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
def process_args(*)
|
|
50
|
+
end
|
|
51
|
+
|
|
39
52
|
class View < ActionView::Base
|
|
40
53
|
def self.prepare(modules)
|
|
41
54
|
# TODO: remove for 4.0 if PR https://github.com/rails/rails/pull/6826 is merged.
|
|
@@ -43,27 +56,27 @@ module Cell
|
|
|
43
56
|
include *modules.reverse
|
|
44
57
|
end
|
|
45
58
|
end
|
|
46
|
-
|
|
59
|
+
|
|
47
60
|
def render(*args, &block)
|
|
48
61
|
options = args.first.is_a?(::Hash) ? args.first : {} # this is copied from #render by intention.
|
|
49
|
-
|
|
62
|
+
|
|
50
63
|
return controller.render(*args, &block) if options[:state] or options[:view]
|
|
51
64
|
super
|
|
52
65
|
end
|
|
53
66
|
end
|
|
54
|
-
|
|
55
|
-
|
|
67
|
+
|
|
68
|
+
|
|
56
69
|
def self.view_context_class
|
|
57
70
|
@view_context_class ||= begin
|
|
58
71
|
Cell::Base::View.prepare(helper_modules)
|
|
59
72
|
end
|
|
60
73
|
end
|
|
61
|
-
|
|
74
|
+
|
|
62
75
|
# Called in Railtie at initialization time.
|
|
63
76
|
def self.setup_view_paths!
|
|
64
77
|
self.view_paths = self::DEFAULT_VIEW_PATHS
|
|
65
78
|
end
|
|
66
|
-
|
|
79
|
+
|
|
67
80
|
def self.controller_path
|
|
68
81
|
@controller_path ||= name.sub(/Cell$/, '').underscore unless anonymous?
|
|
69
82
|
end
|
data/lib/cell/builder.rb
CHANGED
|
@@ -5,19 +5,20 @@ module Cell
|
|
|
5
5
|
# class with Cell::Base.build - this might lead to a different cell being returned.
|
|
6
6
|
def create_cell_for(name, *args)
|
|
7
7
|
class_from_cell_name(name).build_for(*args)
|
|
8
|
-
end
|
|
9
|
-
|
|
8
|
+
end # TODO: rename to #cell_for.
|
|
9
|
+
alias_method :cell_for, :create_cell_for
|
|
10
|
+
|
|
10
11
|
def build_for(*args) # DISCUSS: remove?
|
|
11
12
|
build_class_for(*args).
|
|
12
13
|
create_cell(*args)
|
|
13
14
|
end
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
|
|
16
17
|
# class for rendering. This is helpful if you frequently want to render subclasses according
|
|
17
18
|
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
|
|
18
19
|
# your view code.
|
|
19
20
|
#
|
|
20
|
-
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
|
|
21
|
+
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
|
|
21
22
|
# Multiple build blocks are ORed, if no builder matches the building cell is used.
|
|
22
23
|
#
|
|
23
24
|
# Example:
|
|
@@ -41,17 +42,17 @@ module Cell
|
|
|
41
42
|
def build(&block)
|
|
42
43
|
builders << block
|
|
43
44
|
end
|
|
44
|
-
|
|
45
|
+
|
|
45
46
|
# The cell class constant for +cell_name+.
|
|
46
47
|
def class_from_cell_name(cell_name)
|
|
47
48
|
"#{cell_name}_cell".classify.constantize
|
|
48
49
|
end
|
|
49
|
-
|
|
50
|
+
|
|
50
51
|
# Override this if you want to receive arguments right in the cell constructor.
|
|
51
52
|
def create_cell(*args)
|
|
52
|
-
new
|
|
53
|
+
new(*args)
|
|
53
54
|
end
|
|
54
|
-
|
|
55
|
+
|
|
55
56
|
private
|
|
56
57
|
def build_class_for(*args)
|
|
57
58
|
builders.each do |blk|
|
|
@@ -59,11 +60,11 @@ module Cell
|
|
|
59
60
|
end
|
|
60
61
|
self
|
|
61
62
|
end
|
|
62
|
-
|
|
63
|
+
|
|
63
64
|
def run_builder_block(block, *args)
|
|
64
65
|
block.call(*args)
|
|
65
66
|
end
|
|
66
|
-
|
|
67
|
+
|
|
67
68
|
def builders
|
|
68
69
|
@builders ||= []
|
|
69
70
|
end
|
data/lib/cell/dsl.rb
ADDED
data/lib/cell/rack.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Cell
|
|
|
5
5
|
# in the cell. This is especially useful when using gems like devise with your cell, without the
|
|
6
6
|
# entire Cell::Rails overhead.
|
|
7
7
|
#
|
|
8
|
-
# The only dependency these kinds of cells have is a
|
|
8
|
+
# The only dependency these kinds of cells have is a Rack-compatible request object.
|
|
9
9
|
#
|
|
10
10
|
# Example:
|
|
11
11
|
#
|
|
@@ -16,20 +16,16 @@ module Cell
|
|
|
16
16
|
class Rack < Base
|
|
17
17
|
attr_reader :request
|
|
18
18
|
delegate :session, :params, :to => :request
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
class << self
|
|
21
21
|
# DISCUSS: i don't like these class methods. maybe a RenderingStrategy?
|
|
22
|
-
def create_cell(request, *args) # defined in Builder.
|
|
23
|
-
new(request)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
22
|
def render_cell_state(cell, state, request, *args) # defined in Rendering.
|
|
27
23
|
super(cell, state, *args)
|
|
28
24
|
end
|
|
29
25
|
end
|
|
30
|
-
|
|
31
|
-
def initialize(request)
|
|
32
|
-
super()
|
|
26
|
+
|
|
27
|
+
def initialize(request, *args)
|
|
28
|
+
super(*args)
|
|
33
29
|
@request = request
|
|
34
30
|
end
|
|
35
31
|
end
|
data/lib/cell/rails.rb
CHANGED
|
@@ -4,10 +4,10 @@ module Cell
|
|
|
4
4
|
class Rails < Rack
|
|
5
5
|
# When this file is included we can savely assume that a rails environment with caching, etc. is available.
|
|
6
6
|
include ActionController::RequestForgeryProtection
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
abstract!
|
|
9
9
|
delegate :session, :params, :request, :config, :env, :url_options, :to => :parent_controller
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
class << self
|
|
12
12
|
def cache_store
|
|
13
13
|
# FIXME: i'd love to have an initializer in the cells gem that _sets_ the cache_store attr instead of overriding here.
|
|
@@ -15,33 +15,41 @@ module Cell
|
|
|
15
15
|
# DISCUSS: should this be in Cell::Rails::Caching ?
|
|
16
16
|
ActionController::Base.cache_store
|
|
17
17
|
end
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def expire_cache_key(key, *args) # FIXME: move to Rails.
|
|
20
20
|
expire_cache_key_for(key, cache_store ,*args)
|
|
21
21
|
end
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
private
|
|
24
24
|
# Run builder block in controller instance context.
|
|
25
25
|
def run_builder_block(block, controller, *args)
|
|
26
26
|
controller.instance_exec(*args, &block)
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
|
|
30
|
+
|
|
31
31
|
attr_reader :parent_controller
|
|
32
32
|
alias_method :controller, :parent_controller
|
|
33
|
-
|
|
34
|
-
def initialize(parent_controller)
|
|
35
|
-
super
|
|
33
|
+
|
|
34
|
+
def initialize(parent_controller, *args)
|
|
35
|
+
super(parent_controller, *args) # FIXME: huh?
|
|
36
36
|
@parent_controller = parent_controller
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
def cache_configured?
|
|
40
40
|
ActionController::Base.send(:cache_configured?) # DISCUSS: why is it private?
|
|
41
41
|
end
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
def cache_store
|
|
44
44
|
self.class.cache_store # in Rails, we have a global cache store.
|
|
45
45
|
end
|
|
46
|
+
|
|
47
|
+
module DSL
|
|
48
|
+
def cell(name, *args)
|
|
49
|
+
# TODO: this method should be an instance method everywhere.
|
|
50
|
+
Base.cell_for(name, parent_controller, *args)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
include DSL
|
|
46
54
|
end
|
|
47
55
|
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# no helper_method calls
|
|
2
|
+
# no instance variables
|
|
3
|
+
# no locals
|
|
4
|
+
# options are automatically made instance methods via constructor.
|
|
5
|
+
# call "helpers" in class
|
|
6
|
+
class Cell::Rails
|
|
7
|
+
module ViewModel
|
|
8
|
+
include Cell::OptionsConstructor
|
|
9
|
+
#include ActionView::Helpers::UrlHelper
|
|
10
|
+
include ActionView::Context # this includes CompiledTemplates, too.
|
|
11
|
+
# properties :title, :body
|
|
12
|
+
attr_reader :model
|
|
13
|
+
|
|
14
|
+
module ClassMethods
|
|
15
|
+
def property(name)
|
|
16
|
+
delegate name, :to => :model
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
extend ActiveSupport::Concern
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def render(options={})
|
|
23
|
+
if options.is_a?(Hash)
|
|
24
|
+
options.reverse_merge!(:view => state_for_implicit_render)
|
|
25
|
+
else
|
|
26
|
+
options = {:view => options.to_s}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
super
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def call
|
|
33
|
+
render implicit_state
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
def view_context
|
|
38
|
+
self
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def state_for_implicit_render()
|
|
42
|
+
caller[1].match(/`(\w+)/)[1]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def implicit_state
|
|
46
|
+
controller_path.split("/").last
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# FIXME: this module is to fix a design flaw in Rails 4.0. the problem is that AV::UrlHelper mixes in the wrong #url_for.
|
|
52
|
+
# if we could mix in everything else from the helper except for the #url_for, it would be fine.
|
|
53
|
+
module LinkToHelper
|
|
54
|
+
include ActionView::Helpers::TagHelper
|
|
55
|
+
|
|
56
|
+
def link_to(name = nil, options = nil, html_options = nil, &block)
|
|
57
|
+
html_options, options, name = options, name, block if block_given?
|
|
58
|
+
options ||= {}
|
|
59
|
+
|
|
60
|
+
html_options = convert_options_to_data_attributes(options, html_options)
|
|
61
|
+
|
|
62
|
+
url = url_for(options)
|
|
63
|
+
html_options['href'] ||= url
|
|
64
|
+
|
|
65
|
+
content_tag(:a, name || url, html_options, &block)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def convert_options_to_data_attributes(options, html_options)
|
|
69
|
+
if html_options
|
|
70
|
+
html_options = html_options.stringify_keys
|
|
71
|
+
html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)
|
|
72
|
+
|
|
73
|
+
disable_with = html_options.delete("disable_with")
|
|
74
|
+
confirm = html_options.delete('confirm')
|
|
75
|
+
method = html_options.delete('method')
|
|
76
|
+
|
|
77
|
+
if confirm
|
|
78
|
+
message = ":confirm option is deprecated and will be removed from Rails 4.1. " \
|
|
79
|
+
"Use 'data: { confirm: \'Text\' }' instead."
|
|
80
|
+
ActiveSupport::Deprecation.warn message
|
|
81
|
+
|
|
82
|
+
html_options["data-confirm"] = confirm
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
add_method_to_attributes!(html_options, method) if method
|
|
86
|
+
|
|
87
|
+
if disable_with
|
|
88
|
+
message = ":disable_with option is deprecated and will be removed from Rails 4.1. " \
|
|
89
|
+
"Use 'data: { disable_with: \'Text\' }' instead."
|
|
90
|
+
ActiveSupport::Deprecation.warn message
|
|
91
|
+
|
|
92
|
+
html_options["data-disable-with"] = disable_with
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
html_options
|
|
96
|
+
else
|
|
97
|
+
link_to_remote_options?(options) ? {'data-remote' => 'true'} : {}
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def link_to_remote_options?(options)
|
|
102
|
+
if options.is_a?(Hash)
|
|
103
|
+
options.delete('remote') || options.delete(:remote)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# FIXME: fix that in rails core.
|
|
109
|
+
if Cell.rails4_0_or_more?
|
|
110
|
+
include LinkToHelper
|
|
111
|
+
else
|
|
112
|
+
include ActionView::Helpers::UrlHelper
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|