cells 3.5.1 → 3.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.textile +11 -0
- data/README.rdoc +6 -3
- data/lib/cell.rb +9 -9
- data/lib/cell/caching.rb +7 -6
- data/lib/cell/rails.rb +10 -4
- data/lib/cell/test_case.rb +2 -2
- data/lib/cells/rails.rb +4 -4
- data/lib/cells/version.rb +1 -1
- data/test/cell_module_test.rb +19 -5
- data/test/rails/caching_test.rb +27 -12
- data/test/rails/integration_test.rb +17 -1
- metadata +3 -3
data/CHANGES.textile
CHANGED
@@ -1,4 +1,14 @@
|
|
1
|
+
h2. 3.5.2
|
2
|
+
|
3
|
+
h3. Bugfixes
|
4
|
+
* Controller#render_cell now accepts multiple args as options.
|
5
|
+
|
6
|
+
h3. Changes
|
7
|
+
* Caching versioners now can accept state-args or options from the #render_cell call. This way, you don't have to access #options at all anymore.
|
8
|
+
|
9
|
+
|
1
10
|
h2. 3.5.1
|
11
|
+
|
2
12
|
* No longer pass an explicit Proc but a versioner block to @Cell.Base.cache@. Example: @cache :show do "v1" end@
|
3
13
|
* Caching.cache_key_for now uses @ActiveSupport::Cache.expand_cache_key@. Consequently, a key which used to be like @"cells/director/count/a=1/b=2"@ now is @cells/director/count/a=1&b=2@ and so on. Be warned that this might break your home-made cache expiry.
|
4
14
|
* Controller#expire_cell_state now expects the cell class as first arg. Example: @expire_cell_state(DirectorCell, :count)@
|
@@ -6,6 +16,7 @@ h2. 3.5.1
|
|
6
16
|
h3. Bugfixes
|
7
17
|
* Passing options to @render :state@ in views finally works: @render({:state => :list_item}, item, i)@
|
8
18
|
|
19
|
+
|
9
20
|
h2. 3.5.0
|
10
21
|
|
11
22
|
h3. Changes
|
data/README.rdoc
CHANGED
@@ -124,13 +124,16 @@ Cells do strict view caching. No cluttered fragment caching. Add
|
|
124
124
|
|
125
125
|
and your cart will be re-rendered after 10 minutes.
|
126
126
|
|
127
|
-
|
127
|
+
You can expand the state's cache key - why not use a versioner block to do just this?
|
128
128
|
|
129
129
|
class ShoppingCartCell < Cell::Rails
|
130
|
-
cache :display do |cell|
|
131
|
-
|
130
|
+
cache :display do |cell, options|
|
131
|
+
options[:items].md5
|
132
132
|
end
|
133
133
|
|
134
|
+
The return value is appended to the state key: <tt>"cells/shopping_cart/display/0ecb1360644ce665a4ef"</tt>.
|
135
|
+
|
136
|
+
API here[http://rdoc.info/gems/cells/Cell/Caching/ClassMethods#cache-instance_method].
|
134
137
|
|
135
138
|
== Testing
|
136
139
|
|
data/lib/cell.rb
CHANGED
@@ -4,19 +4,19 @@ module Cell
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
module ClassMethods
|
7
|
-
def render_cell_for(controller, name, state,
|
8
|
-
cell = create_cell_for(controller, name,
|
7
|
+
def render_cell_for(controller, name, state, *args)
|
8
|
+
cell = create_cell_for(controller, name, *args) # DISCUSS: we always save options.
|
9
9
|
yield cell if block_given?
|
10
10
|
|
11
|
-
return cell.render_state(state,
|
11
|
+
return cell.render_state(state, *args) if cell.state_accepts_args?(state)
|
12
12
|
cell.render_state(state) # backward-compat.
|
13
13
|
end
|
14
14
|
|
15
15
|
# Creates a cell instance. Note that this method calls builders which were attached to the
|
16
16
|
# class with Cell::Base.build - this might lead to a different cell being returned.
|
17
|
-
def create_cell_for(controller, name,
|
18
|
-
build_class_for(controller, class_from_cell_name(name),
|
19
|
-
new(controller,
|
17
|
+
def create_cell_for(controller, name, *args)
|
18
|
+
build_class_for(controller, class_from_cell_name(name), *args).
|
19
|
+
new(controller, *args)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
|
@@ -49,9 +49,9 @@ module Cell
|
|
49
49
|
builders << block
|
50
50
|
end
|
51
51
|
|
52
|
-
def build_class_for(controller, target_class,
|
52
|
+
def build_class_for(controller, target_class, *args)
|
53
53
|
target_class.builders.each do |blk|
|
54
|
-
res = controller.instance_exec(
|
54
|
+
res = controller.instance_exec(*args, &blk) and return res
|
55
55
|
end
|
56
56
|
target_class
|
57
57
|
end
|
@@ -91,7 +91,7 @@ module Cell
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def state_accepts_args?(state)
|
94
|
-
method(state).arity
|
94
|
+
method(state).arity > 0
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
data/lib/cell/caching.rb
CHANGED
@@ -21,7 +21,7 @@ module Cell
|
|
21
21
|
#
|
22
22
|
# If you need your own granular cache keys, pass a versioner block.
|
23
23
|
#
|
24
|
-
# cache :show do |cell|
|
24
|
+
# cache :show do |cell, options|
|
25
25
|
# "user/#{cell.options[:id]}"
|
26
26
|
# end
|
27
27
|
#
|
@@ -30,7 +30,7 @@ module Cell
|
|
30
30
|
# Alternatively, use an instance method.
|
31
31
|
#
|
32
32
|
# cache :show, :versioner
|
33
|
-
# def versioner
|
33
|
+
# def versioner(options)
|
34
34
|
# "user/#{options[:id]}"
|
35
35
|
# end
|
36
36
|
#
|
@@ -87,7 +87,7 @@ module Cell
|
|
87
87
|
def render_state(state, *args)
|
88
88
|
return super(state, *args) unless self.class.cache?(state)
|
89
89
|
|
90
|
-
key = self.class.state_cache_key(state, call_state_versioner(state))
|
90
|
+
key = self.class.state_cache_key(state, call_state_versioner(state, *args))
|
91
91
|
options = self.class.cache_options[state]
|
92
92
|
|
93
93
|
self.class.cache_store.fetch(key, options) do
|
@@ -95,11 +95,12 @@ module Cell
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
|
98
|
+
protected
|
99
|
+
def call_state_versioner(state, *args)
|
99
100
|
version_proc = self.class.version_procs[state] or return
|
100
101
|
|
101
|
-
return version_proc.call(self) if version_proc.kind_of?(Proc)
|
102
|
-
send(version_proc)
|
102
|
+
return version_proc.call(self, *args) if version_proc.kind_of?(Proc)
|
103
|
+
state_accepts_args?(state) ? send(version_proc, *args) : send(version_proc)
|
103
104
|
end
|
104
105
|
|
105
106
|
end
|
data/lib/cell/rails.rb
CHANGED
@@ -49,12 +49,18 @@ module Cell
|
|
49
49
|
abstract!
|
50
50
|
|
51
51
|
|
52
|
-
def initialize(parent_controller,
|
52
|
+
def initialize(parent_controller, *args)
|
53
53
|
@parent_controller = parent_controller
|
54
|
-
|
55
|
-
@opts = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :options)
|
54
|
+
setup_backwardibility(*args)
|
56
55
|
end
|
57
|
-
|
56
|
+
|
57
|
+
# Some people still like #options and assume it's a hash.
|
58
|
+
def setup_backwardibility(*args)
|
59
|
+
@options = (args.first.is_a?(Hash) and args.size == 1) ? args.first : args
|
60
|
+
@opts = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :options)
|
61
|
+
end
|
62
|
+
|
63
|
+
|
58
64
|
def self.view_context_class
|
59
65
|
controller = self
|
60
66
|
|
data/lib/cell/test_case.rb
CHANGED
@@ -84,8 +84,8 @@ module Cell
|
|
84
84
|
#
|
85
85
|
# Example:
|
86
86
|
# assert_equal "Banks kill planet!" cell(:news, :topic => :terror).latest_headline
|
87
|
-
def cell(name,
|
88
|
-
cell = ::Cell::Base.create_cell_for(@controller, name,
|
87
|
+
def cell(name, *args, &block)
|
88
|
+
cell = ::Cell::Base.create_cell_for(@controller, name, *args)
|
89
89
|
cell.instance_eval &block if block_given?
|
90
90
|
cell
|
91
91
|
end
|
data/lib/cells/rails.rb
CHANGED
@@ -17,8 +17,8 @@ module Cells
|
|
17
17
|
# @box = render_cell(:comments, :top5) do |cell|
|
18
18
|
# cell.markdown! if config.parse_comments?
|
19
19
|
# end
|
20
|
-
def render_cell(name, state,
|
21
|
-
::Cell::Base.render_cell_for(self, name, state,
|
20
|
+
def render_cell(name, state, *args, &block)
|
21
|
+
::Cell::Base.render_cell_for(self, name, state, *args, &block)
|
22
22
|
end
|
23
23
|
|
24
24
|
# Expires the cached cell state view, similar to ActionController::expire_fragment.
|
@@ -49,8 +49,8 @@ module Cells
|
|
49
49
|
|
50
50
|
module ActionView
|
51
51
|
# See Cells::Rails::ActionController#render_cell.
|
52
|
-
def render_cell(name, state,
|
53
|
-
::Cell::Base.render_cell_for(controller, name, state,
|
52
|
+
def render_cell(name, state, *args, &block)
|
53
|
+
::Cell::Base.render_cell_for(controller, name, state, *args, &block)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
data/lib/cells/version.rb
CHANGED
data/test/cell_module_test.rb
CHANGED
@@ -79,6 +79,9 @@ class CellModuleTest < ActiveSupport::TestCase
|
|
79
79
|
MusicianCell.class_eval do
|
80
80
|
@builders = false
|
81
81
|
end
|
82
|
+
BassistCell.class_eval do
|
83
|
+
@builders = false
|
84
|
+
end
|
82
85
|
end
|
83
86
|
|
84
87
|
should "execute the block in controller context" do
|
@@ -151,11 +154,22 @@ class CellModuleTest < ActiveSupport::TestCase
|
|
151
154
|
assert_equal BassistCell, ::Cell::Base.class_from_cell_name('bassist')
|
152
155
|
end
|
153
156
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
157
|
+
context "#state_accepts_args?" do
|
158
|
+
should "be false if state doesn't want args" do
|
159
|
+
assert_not cell(:bassist).state_accepts_args?(:play)
|
160
|
+
end
|
161
|
+
|
162
|
+
should "be true for one arg" do
|
163
|
+
assert(cell(:bassist) do
|
164
|
+
def listen(args) end
|
165
|
+
end.state_accepts_args?(:listen))
|
166
|
+
end
|
167
|
+
|
168
|
+
should "be true for multiple arg" do
|
169
|
+
assert(cell(:bassist) do
|
170
|
+
def listen(what, where) end
|
171
|
+
end.state_accepts_args?(:listen))
|
172
|
+
end
|
159
173
|
end
|
160
174
|
end
|
161
175
|
end
|
data/test/rails/caching_test.rb
CHANGED
@@ -230,9 +230,9 @@ class CachingFunctionalTest < ActiveSupport::TestCase
|
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
|
-
should "compute the key with
|
234
|
-
@class.cache :count do |cell|
|
235
|
-
(
|
233
|
+
should "compute the key with a block" do
|
234
|
+
@class.cache :count do |cell, int|
|
235
|
+
(int % 2)==0 ? {:count => "even"} : {:count => "odd"}
|
236
236
|
end
|
237
237
|
# example cache key: cells/director/count/count=odd
|
238
238
|
|
@@ -242,25 +242,40 @@ class CachingFunctionalTest < ActiveSupport::TestCase
|
|
242
242
|
assert_equal "2", render_cell(:director, :count, 4)
|
243
243
|
end
|
244
244
|
|
245
|
+
should "still be able to use options in the block" do
|
246
|
+
@class.class_eval do
|
247
|
+
def count(args)
|
248
|
+
render :text => args[:int]
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
@class.cache :count do |cell, i|
|
253
|
+
(cell.options[:int] % 2)==0 ? {:count => "even"} : {:count => "odd"}
|
254
|
+
end
|
255
|
+
|
256
|
+
assert_equal "1", render_cell(:director, :count, :int => 1)
|
257
|
+
assert_equal "2", render_cell(:director, :count, :int => 2)
|
258
|
+
assert_equal "1", render_cell(:director, :count, :int => 3)
|
259
|
+
assert_equal "2", render_cell(:director, :count, :int => 4)
|
260
|
+
end
|
261
|
+
|
245
262
|
should "compute the key with an instance method" do
|
246
263
|
@class.cache :count, :version
|
247
264
|
@class.class_eval do
|
248
|
-
def version
|
249
|
-
(
|
265
|
+
def version(int)
|
266
|
+
(int % 2)==0 ? {:count => "even"} : {:count => "odd"}
|
250
267
|
end
|
251
268
|
end
|
252
269
|
|
253
270
|
assert_equal "1", render_cell(:director, :count, 1)
|
254
|
-
assert_equal "
|
255
|
-
assert_equal "
|
256
|
-
assert_equal "
|
257
|
-
assert_equal "1", render_cell(:director, :count, 5)
|
258
|
-
assert_equal "3", render_cell(:director, :count, 6)
|
271
|
+
assert_equal "2", render_cell(:director, :count, 2)
|
272
|
+
assert_equal "1", render_cell(:director, :count, 3)
|
273
|
+
assert_equal "2", render_cell(:director, :count, 4)
|
259
274
|
end
|
260
275
|
|
261
276
|
should "allow returning strings, too" do
|
262
|
-
@class.cache :count do |cell|
|
263
|
-
(
|
277
|
+
@class.cache :count do |cell, int|
|
278
|
+
(int % 2)==0 ? "even" : "odd"
|
264
279
|
end
|
265
280
|
|
266
281
|
assert_equal "1", render_cell(:director, :count, 1)
|
@@ -4,11 +4,27 @@ class RailsIntegrationTest < ActionController::TestCase
|
|
4
4
|
tests MusicianController
|
5
5
|
|
6
6
|
context "A Rails controller" do
|
7
|
-
should "respond to render_cell" do
|
7
|
+
should "respond to #render_cell" do
|
8
8
|
get 'promotion'
|
9
9
|
assert_equal "That's me, naked <img alt=\"Me\" src=\"/images/me.png\" />", @response.body
|
10
10
|
end
|
11
11
|
|
12
|
+
should "respond to #render_cell with arbitrary options" do
|
13
|
+
BassistCell.class_eval do
|
14
|
+
def enjoy(what, where)
|
15
|
+
render :text => "I like #{what} in #{where}."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
@controller.instance_eval do
|
20
|
+
def promotion
|
21
|
+
render :text => render_cell(:bassist, :enjoy, "The Stranglers", "my room")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
get 'promotion'
|
25
|
+
assert_equal "I like The Stranglers in my room.", @response.body
|
26
|
+
end
|
27
|
+
|
12
28
|
should "be able to pass a block to #render_cell" do
|
13
29
|
get 'promotion_with_block'
|
14
30
|
assert_equal "Doo", @response.body
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 3
|
7
7
|
- 5
|
8
|
-
-
|
9
|
-
version: 3.5.
|
8
|
+
- 2
|
9
|
+
version: 3.5.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Nick Sutterer
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-02-
|
17
|
+
date: 2011-02-11 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|