cells-collection 0.0.1
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +53 -0
- data/Rakefile +4 -0
- data/cells-collection.gemspec +27 -0
- data/lib/cells-collection.rb +4 -0
- data/lib/cells-collection/cell/caching.rb +63 -0
- data/lib/cells-collection/cell/rendering.rb +24 -0
- data/lib/cells-collection/cells/rails.rb +15 -0
- data/lib/cells-collection/version.rb +5 -0
- data/spec/cells/rails_spec.rb +12 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 459248934c448a5cdce15676b038b66c1cae5309
|
4
|
+
data.tar.gz: 7f150d4c455faccec2f4f571a7d9f0a881420450
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fac847494f6b6ea3c881a6134292a37f6fcd0b4369032518badebd59da36d55a30d4957ece806dad573e439bb3264678f826543ba9b21f45ee0a8546297905c2
|
7
|
+
data.tar.gz: 7a906a51f7bb23c305ccfa78197ea0ad01cd1a1c07a4795f391bf88e062cf3a2dfa022ef2e6331a32896c8a9db30c129a03df0a49c47eed359e9c04913cf2929
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 lulalala
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Cells::Collection
|
2
|
+
|
3
|
+
Allows [cell](https://github.com/apotonick/cells) rendering for a collection of items in one go.
|
4
|
+
|
5
|
+
This allows Rails to utilize cache store's `get_multi` method. When cache store supports it (e.g. Memcached), this results in only one cache read request for the whole collection.
|
6
|
+
|
7
|
+
The performance boost does vary from action to action, so always benchmark to see if it improved the performance. Two biggest boost can happen when:
|
8
|
+
|
9
|
+
* Cache store lives at a remote location.
|
10
|
+
* Collection size over 50 items.
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile **after** cells gem declaration:
|
15
|
+
|
16
|
+
gem 'cells'
|
17
|
+
gem 'cells-collection'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle install
|
22
|
+
|
23
|
+
To setup Rails to use Memcached store, take look at the [dalli gem](https://github.com/mperham/dalli).
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
Doing this in the view:
|
28
|
+
|
29
|
+
<%= render_cell_collection :cart, :item, @items %>
|
30
|
+
|
31
|
+
will be equivalent to the old:
|
32
|
+
|
33
|
+
<% @items.each do |item| %>
|
34
|
+
<%= render_cell :cart, :item, item %>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
If the cell requires more arguments, they can be passed at the end. They will be passed to each cell rendering too:
|
38
|
+
|
39
|
+
<%= render_cell_collection :cart, :item, @items, 'hot', 10 %>
|
40
|
+
|
41
|
+
is equivalent to:
|
42
|
+
|
43
|
+
<% @items.each do |item| %>
|
44
|
+
<%= render_cell :cart, :item, item, 'hot', 10 %>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
## Contributing
|
48
|
+
|
49
|
+
1. Fork it
|
50
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
51
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
52
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
53
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cells-collection/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cells-collection"
|
8
|
+
spec.version = Cells::Collection::VERSION
|
9
|
+
spec.authors = ["GoodLife", "lulalala"]
|
10
|
+
spec.email = ["mark@goodlife.tw"]
|
11
|
+
spec.description = %q{Cells rendering for a collection of items, utilizing cache bulk-read.}
|
12
|
+
spec.summary = %q{Cells rendering for a collection of items}
|
13
|
+
spec.homepage = "https://github.com/GoodLife/cells-collection"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'cells', '~> 3.8'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
|
26
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
27
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'active_support/cache'
|
2
|
+
|
3
|
+
module Cell
|
4
|
+
module Caching
|
5
|
+
module ClassMethods
|
6
|
+
def render_cell_collection_for(name, state, *args)
|
7
|
+
args_for_single = args.dup
|
8
|
+
collection = args[1]
|
9
|
+
|
10
|
+
return '' if collection.empty?
|
11
|
+
|
12
|
+
item_to_key = {}
|
13
|
+
item_to_key.compare_by_identity
|
14
|
+
item_to_cell = {} # Cache initialized cell object
|
15
|
+
item_to_cell.compare_by_identity
|
16
|
+
|
17
|
+
# Create item-key mapping table for cacheable cells
|
18
|
+
collection.each do |item|
|
19
|
+
args_for_single[1] = item # Prepare args for single item
|
20
|
+
cell = create_cell_for(name, *args_for_single)
|
21
|
+
|
22
|
+
item_to_cell[item] = cell
|
23
|
+
|
24
|
+
if cell.cache?(state, *args)
|
25
|
+
# Remove first arg, because compute_key does not want the cell object as first argument.
|
26
|
+
# I don't know where is this stripped in single cell rendering code.
|
27
|
+
item_to_key[item] = cell.compute_key(state, *(args_for_single[1..-1]))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# cache.read_multi & cache.write interfaces may require mutable keys, ie. dalli 2.6.0
|
32
|
+
mutable_keys = item_to_key.values.map(&:dup)
|
33
|
+
|
34
|
+
if options = cache_options[state]
|
35
|
+
cached = cache_store.read_multi(*mutable_keys, options)
|
36
|
+
else
|
37
|
+
cached = cache_store.read_multi(*mutable_keys)
|
38
|
+
end
|
39
|
+
|
40
|
+
rendered = ''
|
41
|
+
|
42
|
+
collection.each do |item|
|
43
|
+
# Get key of item, and check if cached has that key
|
44
|
+
if cached_result = cached[item_to_key[item]]
|
45
|
+
rendered << cached_result
|
46
|
+
else
|
47
|
+
cell = item_to_cell[item]
|
48
|
+
yield cell if block_given?
|
49
|
+
|
50
|
+
args_for_single[1] = item # Prepare args for single item
|
51
|
+
rendered << render_cell_state(cell, state, *args_for_single)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
return rendered.html_safe
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def compute_key(state, *args)
|
60
|
+
self.class.state_cache_key(state, call_state_versioner(state, *args))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Cell
|
2
|
+
module Rendering
|
3
|
+
module ClassMethods
|
4
|
+
# Rendering collection of cells
|
5
|
+
def render_cell_collection_for(name, state, *args)
|
6
|
+
args_for_single = args.dup
|
7
|
+
collection = args[1]
|
8
|
+
|
9
|
+
rendered = ''
|
10
|
+
|
11
|
+
collection.each do |item|
|
12
|
+
args_for_single[1] = item
|
13
|
+
|
14
|
+
cell = create_cell_for(name, *args_for_single)
|
15
|
+
yield cell if block_given?
|
16
|
+
|
17
|
+
rendered << render_cell_state(cell, state, *args_for_single)
|
18
|
+
end
|
19
|
+
|
20
|
+
return rendered.html_safe
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Cells
|
2
|
+
module Rails
|
3
|
+
module ActionController
|
4
|
+
def render_cell_collection(name, state, *args, &block)
|
5
|
+
::Cell::Rails.render_cell_collection_for(name, state, self, *args, &block)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module ActionView
|
10
|
+
def render_cell_collection(name, state, *args, &block)
|
11
|
+
::Cell::Rails.render_cell_collection_for(name, state, controller, *args, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'cells/rails'
|
2
|
+
require 'cells-collection/cells/rails'
|
3
|
+
|
4
|
+
describe Cells::Rails::ActionView do
|
5
|
+
describe '#render_cell_collection' do
|
6
|
+
subject{ Object.new.extend(Cells::Rails::ActionView) }
|
7
|
+
it 'calls render_cell_collection_for' do
|
8
|
+
::Cell::Rails.should_receive(:render_cell_collection)
|
9
|
+
subject.render_cell_collection
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cells-collection
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- GoodLife
|
8
|
+
- lulalala
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cells
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.8'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.8'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '2.14'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2.14'
|
70
|
+
description: Cells rendering for a collection of items, utilizing cache bulk-read.
|
71
|
+
email:
|
72
|
+
- mark@goodlife.tw
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- cells-collection.gemspec
|
83
|
+
- lib/cells-collection.rb
|
84
|
+
- lib/cells-collection/cell/caching.rb
|
85
|
+
- lib/cells-collection/cell/rendering.rb
|
86
|
+
- lib/cells-collection/cells/rails.rb
|
87
|
+
- lib/cells-collection/version.rb
|
88
|
+
- spec/cells/rails_spec.rb
|
89
|
+
homepage: https://github.com/GoodLife/cells-collection
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.0.5
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Cells rendering for a collection of items
|
113
|
+
test_files:
|
114
|
+
- spec/cells/rails_spec.rb
|
115
|
+
has_rdoc:
|