materializer 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.
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +6 -0
- data/Appraisals +5 -0
- data/Gemfile +4 -0
- data/Guardfile +9 -0
- data/LICENSE +21 -0
- data/README.rdoc +61 -0
- data/Rakefile +28 -0
- data/db/schema.rb +19 -0
- data/gemfiles/rails-3.1.0.gemfile +7 -0
- data/gemfiles/rails-3.1.0.gemfile.lock +154 -0
- data/lib/materializer.rb +13 -0
- data/lib/materializer/base.rb +73 -0
- data/lib/materializer/core_ext.rb +30 -0
- data/lib/materializer/version.rb +5 -0
- data/materializer.gemspec +45 -0
- data/spec/controllers/garages_controller_spec.rb +41 -0
- data/spec/database.yml +7 -0
- data/spec/models/garage_spec.rb +61 -0
- data/spec/spec_helper.rb +41 -0
- data/spec/support/controllers.rb +23 -0
- data/spec/support/factories.rb +12 -0
- data/spec/support/models.rb +26 -0
- data/spec/support/routes.rb +5 -0
- metadata +275 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2@materializer --create
|
data/.travis.yml
ADDED
data/Appraisals
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2011 Christopher Meiklejohn
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
= Materializer
|
2
|
+
|
3
|
+
Persist serialization in the model by front-loading the serialization
|
4
|
+
and storing in the database as a string.
|
5
|
+
|
6
|
+
== Usage
|
7
|
+
|
8
|
+
Using Materializer is easy!
|
9
|
+
|
10
|
+
=== How to include an enable it?
|
11
|
+
|
12
|
+
It's easy. First, add the gem:
|
13
|
+
|
14
|
+
gem 'materializer'
|
15
|
+
|
16
|
+
Enable materializer in the models you which to maintain rendered views
|
17
|
+
in.
|
18
|
+
|
19
|
+
include Materializer
|
20
|
+
|
21
|
+
Then, define one or more materialization profiles:
|
22
|
+
|
23
|
+
materialize :into => FIELD_NAME, :using => METHOD_NAME
|
24
|
+
|
25
|
+
You'll also need to make a migration to add the column:
|
26
|
+
|
27
|
+
t.string FIELD_NAME_json
|
28
|
+
|
29
|
+
Voila!
|
30
|
+
|
31
|
+
FIELD_NAME will be populated with the JSON generated from
|
32
|
+
METHOD_NAME on save. METHOD_NAME should be implemented as a
|
33
|
+
serializable_hash method returning a hash.
|
34
|
+
|
35
|
+
=== Examples
|
36
|
+
|
37
|
+
Some examples on usage:
|
38
|
+
|
39
|
+
==== Materialize data into name_json using the name_as_json method.
|
40
|
+
|
41
|
+
materialize :into => :name, :using => :name_as_json
|
42
|
+
|
43
|
+
==== Materialize data into all_json using the as_json method.
|
44
|
+
|
45
|
+
materialize :into => :all, :using => :as_json
|
46
|
+
|
47
|
+
==== Pull in objects from other models
|
48
|
+
|
49
|
+
materialize :into => :all, :using => :all_as_json
|
50
|
+
|
51
|
+
def all_as_json
|
52
|
+
{ :field1 => field1, :association1 => association1.as_json }
|
53
|
+
end
|
54
|
+
|
55
|
+
== License
|
56
|
+
|
57
|
+
Materializer is Copyright © 2011 Christopher Meiklejohn. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
58
|
+
|
59
|
+
== About
|
60
|
+
|
61
|
+
The materializer gem was written by {Christopher Meiklejohn}[mailto:cmeiklejohn@swipely.com] from {Swipely, Inc.}[http://www.swipely.com].
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'bundler/gem_tasks'
|
6
|
+
require 'rake'
|
7
|
+
require 'rdoc/task'
|
8
|
+
require 'rubygems/package_task'
|
9
|
+
require 'rspec/core/rake_task'
|
10
|
+
require 'appraisal'
|
11
|
+
|
12
|
+
desc "Default: run the specs"
|
13
|
+
task :default => [:all]
|
14
|
+
|
15
|
+
desc 'Test the plugin under all supported Rails versions.'
|
16
|
+
task :all => ["appraisal:install"] do |t|
|
17
|
+
exec('rake appraisal spec')
|
18
|
+
end
|
19
|
+
|
20
|
+
RSpec::Core::RakeTask.new do |t|
|
21
|
+
t.pattern = 'spec/**/*_spec.rb'
|
22
|
+
end
|
23
|
+
|
24
|
+
RDoc::Task.new do |rdoc|
|
25
|
+
rdoc.main = "README.rdoc"
|
26
|
+
rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
27
|
+
rdoc.options << '-f' << 'horo'
|
28
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
ActiveRecord::Schema.define do
|
4
|
+
self.verbose = false
|
5
|
+
|
6
|
+
create_table :garages, :force => true do |t|
|
7
|
+
t.string :name
|
8
|
+
t.string :location
|
9
|
+
t.string :name_json
|
10
|
+
t.string :all_json
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
|
14
|
+
create_table :cars, :force => true do |t|
|
15
|
+
t.string :name
|
16
|
+
t.integer :garage_id
|
17
|
+
t.timestamps
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
PATH
|
2
|
+
remote: /home/cmeiklejohn/Repositories/materializer
|
3
|
+
specs:
|
4
|
+
materializer (0.0.1)
|
5
|
+
rails (>= 3.1.0.rc4)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: http://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ZenTest (4.6.2)
|
11
|
+
actionmailer (3.1.0)
|
12
|
+
actionpack (= 3.1.0)
|
13
|
+
mail (~> 2.3.0)
|
14
|
+
actionpack (3.1.0)
|
15
|
+
activemodel (= 3.1.0)
|
16
|
+
activesupport (= 3.1.0)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
i18n (~> 0.6)
|
20
|
+
rack (~> 1.3.2)
|
21
|
+
rack-cache (~> 1.0.3)
|
22
|
+
rack-mount (~> 0.8.2)
|
23
|
+
rack-test (~> 0.6.1)
|
24
|
+
sprockets (~> 2.0.0)
|
25
|
+
activemodel (3.1.0)
|
26
|
+
activesupport (= 3.1.0)
|
27
|
+
bcrypt-ruby (~> 3.0.0)
|
28
|
+
builder (~> 3.0.0)
|
29
|
+
i18n (~> 0.6)
|
30
|
+
activerecord (3.1.0)
|
31
|
+
activemodel (= 3.1.0)
|
32
|
+
activesupport (= 3.1.0)
|
33
|
+
arel (~> 2.2.1)
|
34
|
+
tzinfo (~> 0.3.29)
|
35
|
+
activeresource (3.1.0)
|
36
|
+
activemodel (= 3.1.0)
|
37
|
+
activesupport (= 3.1.0)
|
38
|
+
activesupport (3.1.0)
|
39
|
+
multi_json (~> 1.0)
|
40
|
+
appraisal (0.3.8)
|
41
|
+
bundler
|
42
|
+
rake
|
43
|
+
arel (2.2.1)
|
44
|
+
bcrypt-ruby (3.0.1)
|
45
|
+
builder (3.0.0)
|
46
|
+
diesel (0.1.5)
|
47
|
+
railties
|
48
|
+
diff-lcs (1.1.3)
|
49
|
+
erubis (2.7.0)
|
50
|
+
factory_girl (2.1.0)
|
51
|
+
factory_girl_rails (1.2.0)
|
52
|
+
factory_girl (~> 2.1.0)
|
53
|
+
railties (>= 3.0.0)
|
54
|
+
ffi (1.0.9)
|
55
|
+
guard (0.7.0)
|
56
|
+
thor (~> 0.14.6)
|
57
|
+
guard-rspec (0.4.5)
|
58
|
+
guard (>= 0.4.0)
|
59
|
+
hike (1.2.1)
|
60
|
+
horo (1.0.3)
|
61
|
+
rdoc (>= 2.5)
|
62
|
+
i18n (0.6.0)
|
63
|
+
libnotify (0.5.7)
|
64
|
+
mail (2.3.0)
|
65
|
+
i18n (>= 0.4.0)
|
66
|
+
mime-types (~> 1.16)
|
67
|
+
treetop (~> 1.4.8)
|
68
|
+
metaclass (0.0.1)
|
69
|
+
mime-types (1.16)
|
70
|
+
mocha (0.10.0)
|
71
|
+
metaclass (~> 0.0.1)
|
72
|
+
multi_json (1.0.3)
|
73
|
+
polyglot (0.3.2)
|
74
|
+
rack (1.3.3)
|
75
|
+
rack-cache (1.0.3)
|
76
|
+
rack (>= 0.4)
|
77
|
+
rack-mount (0.8.3)
|
78
|
+
rack (>= 1.0.0)
|
79
|
+
rack-ssl (1.3.2)
|
80
|
+
rack
|
81
|
+
rack-test (0.6.1)
|
82
|
+
rack (>= 1.0)
|
83
|
+
rails (3.1.0)
|
84
|
+
actionmailer (= 3.1.0)
|
85
|
+
actionpack (= 3.1.0)
|
86
|
+
activerecord (= 3.1.0)
|
87
|
+
activeresource (= 3.1.0)
|
88
|
+
activesupport (= 3.1.0)
|
89
|
+
bundler (~> 1.0)
|
90
|
+
railties (= 3.1.0)
|
91
|
+
railties (3.1.0)
|
92
|
+
actionpack (= 3.1.0)
|
93
|
+
activesupport (= 3.1.0)
|
94
|
+
rack-ssl (~> 1.3.2)
|
95
|
+
rake (>= 0.8.7)
|
96
|
+
rdoc (~> 3.4)
|
97
|
+
thor (~> 0.14.6)
|
98
|
+
rake (0.9.2)
|
99
|
+
rb-inotify (0.8.6)
|
100
|
+
ffi (>= 0.5.0)
|
101
|
+
rdoc (3.9.4)
|
102
|
+
rspec (2.6.0)
|
103
|
+
rspec-core (~> 2.6.0)
|
104
|
+
rspec-expectations (~> 2.6.0)
|
105
|
+
rspec-mocks (~> 2.6.0)
|
106
|
+
rspec-core (2.6.4)
|
107
|
+
rspec-expectations (2.6.0)
|
108
|
+
diff-lcs (~> 1.1.2)
|
109
|
+
rspec-mocks (2.6.0)
|
110
|
+
rspec-rails (2.6.1)
|
111
|
+
actionpack (~> 3.0)
|
112
|
+
activesupport (~> 3.0)
|
113
|
+
railties (~> 3.0)
|
114
|
+
rspec (~> 2.6.0)
|
115
|
+
simplecov (0.5.3)
|
116
|
+
multi_json (~> 1.0.3)
|
117
|
+
simplecov-html (~> 0.5.3)
|
118
|
+
simplecov-html (0.5.3)
|
119
|
+
sprockets (2.0.0)
|
120
|
+
hike (~> 1.2)
|
121
|
+
rack (~> 1.0)
|
122
|
+
tilt (~> 1.1, != 1.3.0)
|
123
|
+
sqlite3 (1.3.4)
|
124
|
+
thor (0.14.6)
|
125
|
+
tilt (1.3.3)
|
126
|
+
timecop (0.3.5)
|
127
|
+
treetop (1.4.10)
|
128
|
+
polyglot
|
129
|
+
polyglot (>= 0.3.1)
|
130
|
+
tzinfo (0.3.29)
|
131
|
+
|
132
|
+
PLATFORMS
|
133
|
+
ruby
|
134
|
+
|
135
|
+
DEPENDENCIES
|
136
|
+
ZenTest
|
137
|
+
appraisal (~> 0.3.5)
|
138
|
+
bundler (~> 1.0.0)
|
139
|
+
diesel
|
140
|
+
factory_girl
|
141
|
+
factory_girl_rails
|
142
|
+
guard
|
143
|
+
guard-rspec
|
144
|
+
horo
|
145
|
+
libnotify
|
146
|
+
materializer!
|
147
|
+
mocha
|
148
|
+
rails (= 3.1.0)
|
149
|
+
rb-inotify
|
150
|
+
rspec
|
151
|
+
rspec-rails
|
152
|
+
simplecov
|
153
|
+
sqlite3
|
154
|
+
timecop
|
data/lib/materializer.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Materializer # :nodoc:
|
4
|
+
module Base # :nodoc:
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
|
10
|
+
# Store all of the materializers.
|
11
|
+
#
|
12
|
+
cattr_accessor :materializers
|
13
|
+
|
14
|
+
# Trigger materialization on save.
|
15
|
+
#
|
16
|
+
after_save :materialize!
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
|
22
|
+
# Instruct the class, on save to materialize using a method into a
|
23
|
+
# particular attribute.
|
24
|
+
#
|
25
|
+
def materialize(options)
|
26
|
+
self.send(:materializers=, []) if self.send(:materializers).nil?
|
27
|
+
self.add_materializer(options)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add a materializer profile.
|
31
|
+
#
|
32
|
+
def add_materializer(options) # :nodoc:
|
33
|
+
materializers = self.send(:materializers)
|
34
|
+
materializers << options
|
35
|
+
self.send(:materializers=, materializers)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
module InstanceMethods
|
41
|
+
|
42
|
+
# Materialize.
|
43
|
+
#
|
44
|
+
# after_save hook to create all of the rendered json
|
45
|
+
# representations based on materialzation profiles.
|
46
|
+
#
|
47
|
+
def materialize!
|
48
|
+
self.send(:materializers).each do |materializer|
|
49
|
+
using_method = materializer[:using]
|
50
|
+
into_attribute = to_materialized_field_name(materializer[:into])
|
51
|
+
generated = ActiveSupport::JSON.encode(self.send(using_method.to_sym))
|
52
|
+
|
53
|
+
self.send(:update_column, into_attribute, generated)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Return content from a materialized profile.
|
58
|
+
#
|
59
|
+
def from_materialized(options)
|
60
|
+
self.send(to_materialized_field_name(options[:profile]))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Convert a profile name into the column name where we'll store
|
64
|
+
# the data.
|
65
|
+
#
|
66
|
+
def to_materialized_field_name(name) # :nodoc:
|
67
|
+
"#{name}_json"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Materializer # :nodoc:
|
4
|
+
module CoreExt # :nodoc:
|
5
|
+
module Array
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module InstanceMethods
|
9
|
+
|
10
|
+
# Return content from a materialized profile.
|
11
|
+
#
|
12
|
+
def from_materialized(options)
|
13
|
+
map do |o|
|
14
|
+
|
15
|
+
# Unfortunately, need to unescape to properly combine it.
|
16
|
+
#
|
17
|
+
# This is still extremely faster, by an order of 5% or
|
18
|
+
# percent faster.
|
19
|
+
#
|
20
|
+
ActiveSupport::JSON.decode(o.from_materialized(options))
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Array.send :include, Materializer::CoreExt::Array
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "materializer/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "materializer"
|
8
|
+
s.version = Materializer::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Christopher Meiklejohn"]
|
11
|
+
s.email = ["christopher.meiklejohn@gmail.com"]
|
12
|
+
s.homepage = "https://github.com/cmeiklejohn/materializer"
|
13
|
+
s.summary = %q{Persist serialization in the model.}
|
14
|
+
s.description = s.summary
|
15
|
+
|
16
|
+
s.rubyforge_project = "materializer"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency('rails', '>= 3.1.0.rc4')
|
24
|
+
|
25
|
+
s.add_development_dependency('bundler', '~> 1.0.0')
|
26
|
+
s.add_development_dependency('rspec')
|
27
|
+
s.add_development_dependency('rspec-rails')
|
28
|
+
s.add_development_dependency('sqlite3')
|
29
|
+
s.add_development_dependency('factory_girl')
|
30
|
+
s.add_development_dependency('factory_girl_rails')
|
31
|
+
s.add_development_dependency('mocha')
|
32
|
+
s.add_development_dependency('appraisal', '~> 0.3.5')
|
33
|
+
s.add_development_dependency('timecop')
|
34
|
+
s.add_development_dependency('horo')
|
35
|
+
s.add_development_dependency('simplecov')
|
36
|
+
s.add_development_dependency('diesel')
|
37
|
+
s.add_development_dependency('ZenTest')
|
38
|
+
s.add_development_dependency('guard')
|
39
|
+
s.add_development_dependency('guard-rspec')
|
40
|
+
|
41
|
+
if RUBY_PLATFORM =~ /linux/i
|
42
|
+
s.add_development_dependency('rb-inotify')
|
43
|
+
s.add_development_dependency('libnotify')
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe GaragesController do
|
6
|
+
|
7
|
+
it "should return all formatted json" do
|
8
|
+
@garages = []
|
9
|
+
2.times do
|
10
|
+
@garage = Factory.create(:garage, :name => 'Chris')
|
11
|
+
@garages << @garage
|
12
|
+
end
|
13
|
+
|
14
|
+
Garage.should_receive(:all).and_return(@garages)
|
15
|
+
|
16
|
+
get 'index', :format => :json
|
17
|
+
|
18
|
+
# Make sure whatever is returned from actionview to the client can
|
19
|
+
# be parsed and is valid.
|
20
|
+
#
|
21
|
+
garages = JSON.parse(response.body)
|
22
|
+
garages.count.should == 2
|
23
|
+
garages.first['name'].should == @garages.first.name
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return the formatted json" do
|
27
|
+
@garage = Factory.create(:garage, :name => 'Chris')
|
28
|
+
|
29
|
+
Garage.should_receive(:find).with("1").and_return(@garage)
|
30
|
+
|
31
|
+
get 'show', :id => '1', :format => :json
|
32
|
+
response.body.should == @garage.name_json
|
33
|
+
|
34
|
+
# Make sure whatever is returned from actionview to the client can
|
35
|
+
# be parsed and is valid.
|
36
|
+
#
|
37
|
+
garage = JSON.parse(response.body)
|
38
|
+
garage['name'].should == @garage.name
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/spec/database.yml
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Garage do
|
6
|
+
|
7
|
+
it "should populate materializers" do
|
8
|
+
@garage = Factory.create(:garage, :name => 'the-name', :location => 'the-location')
|
9
|
+
|
10
|
+
@garage.materializers.should == [
|
11
|
+
{ :into => :name, :using => :name_as_json },
|
12
|
+
{ :into => :all, :using => :as_json }
|
13
|
+
]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should materialize into names after save" do
|
17
|
+
@garage = Factory.create(:garage, :name => 'the-name', :location => 'the-location')
|
18
|
+
|
19
|
+
@garage.name_json.should == @garage.from_materialized(:profile => :name)
|
20
|
+
@garage.name_json.should == {:name => "the-name"}.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should materialize into all after save" do
|
24
|
+
@garage = Factory.create(:garage, :name => 'the-name', :location => 'the-location')
|
25
|
+
|
26
|
+
@garage.all_json.should == @garage.from_materialized(:profile => :all)
|
27
|
+
@garage.all_json.should == {:name => "the-name", :location => "the-location", :cars => []}.to_json
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should render the objects faster than normally" do
|
31
|
+
@garages = []
|
32
|
+
@output = []
|
33
|
+
|
34
|
+
10.times do
|
35
|
+
@garage = Factory.create(:garage)
|
36
|
+
2.times do
|
37
|
+
@car = Factory.create(:car)
|
38
|
+
@garage.cars << @car
|
39
|
+
end
|
40
|
+
@garages << @garage
|
41
|
+
end
|
42
|
+
|
43
|
+
time_before_native = Time.now.to_f
|
44
|
+
@garages.each do |g|
|
45
|
+
@output << g.as_json.to_json
|
46
|
+
end
|
47
|
+
time_after_native = Time.now.to_f
|
48
|
+
|
49
|
+
time_before_optimized = Time.now.to_f
|
50
|
+
@garages.each do |g|
|
51
|
+
@output << g.from_materialized(:profile => :all)
|
52
|
+
end
|
53
|
+
time_after_optimized = Time.now.to_f
|
54
|
+
|
55
|
+
optimized_time = (time_after_optimized - time_before_optimized)
|
56
|
+
normal_time = (time_after_native - time_before_native)
|
57
|
+
|
58
|
+
optimized_time.should < normal_time
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
ENV["RAILS_ENV"] ||= "test"
|
4
|
+
|
5
|
+
PROJECT_ROOT = File.expand_path("../..", __FILE__)
|
6
|
+
$LOAD_PATH << File.join(PROJECT_ROOT, "lib")
|
7
|
+
|
8
|
+
require 'rails/all'
|
9
|
+
require 'rails/test_help'
|
10
|
+
Bundler.require
|
11
|
+
|
12
|
+
require 'diesel/testing'
|
13
|
+
require 'rspec/rails'
|
14
|
+
|
15
|
+
require 'factory_girl_rails'
|
16
|
+
require 'timecop'
|
17
|
+
|
18
|
+
require 'materializer'
|
19
|
+
|
20
|
+
if RUBY_VERSION > "1.9"
|
21
|
+
require 'simplecov'
|
22
|
+
SimpleCov.start
|
23
|
+
end
|
24
|
+
|
25
|
+
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
|
26
|
+
|
27
|
+
ActiveRecord::Base.establish_connection(
|
28
|
+
:adapter => "sqlite3",
|
29
|
+
:database => ":memory:"
|
30
|
+
)
|
31
|
+
|
32
|
+
ActiveRecord::Base.silence do
|
33
|
+
ActiveRecord::Migration.verbose = false
|
34
|
+
|
35
|
+
load(File.dirname(__FILE__) + '/../db/schema.rb')
|
36
|
+
end
|
37
|
+
|
38
|
+
RSpec.configure do |config|
|
39
|
+
config.use_transactional_fixtures = true
|
40
|
+
config.backtrace_clean_patterns << %r{gems/}
|
41
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class GaragesController < ActionController::Base
|
4
|
+
def index
|
5
|
+
@garages = Garage.all
|
6
|
+
|
7
|
+
respond_to do |format|
|
8
|
+
format.json do
|
9
|
+
render :json => @garages.from_materialized(:profile => :name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def show
|
15
|
+
@garage = Garage.find(params[:id])
|
16
|
+
|
17
|
+
respond_to do |format|
|
18
|
+
format.json do
|
19
|
+
render :json => @garage.from_materialized(:profile => :name)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
Factory.define :garage do |garage|
|
6
|
+
garage.sequence(:name) { |n| "name-#{n}" }
|
7
|
+
garage.sequence(:location) { |n| "location-#{n}" }
|
8
|
+
end
|
9
|
+
|
10
|
+
Factory.define :car do |car|
|
11
|
+
car.sequence(:name) { |n| "name-#{n}" }
|
12
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
class Garage < ActiveRecord::Base
|
4
|
+
include Materializer
|
5
|
+
|
6
|
+
has_many :cars
|
7
|
+
|
8
|
+
materialize :into => :name, :using => :name_as_json
|
9
|
+
materialize :into => :all, :using => :as_json
|
10
|
+
|
11
|
+
def name_as_json
|
12
|
+
{ :name => name }
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json
|
16
|
+
{ :name => name, :location => location, :cars => cars.map { |c| c.as_json } }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Car < ActiveRecord::Base
|
21
|
+
belongs_to :garage
|
22
|
+
|
23
|
+
def as_json
|
24
|
+
{ :name => name }
|
25
|
+
end
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,275 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: materializer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Christopher Meiklejohn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-17 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &16209220 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.1.0.rc4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *16209220
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &16207960 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.0
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *16207960
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &16206860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *16206860
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-rails
|
49
|
+
requirement: &16206200 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *16206200
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sqlite3
|
60
|
+
requirement: &16205520 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *16205520
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: factory_girl
|
71
|
+
requirement: &16204600 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *16204600
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: factory_girl_rails
|
82
|
+
requirement: &16204080 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *16204080
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: mocha
|
93
|
+
requirement: &16202260 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *16202260
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: appraisal
|
104
|
+
requirement: &16173920 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.3.5
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *16173920
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: timecop
|
115
|
+
requirement: &16172960 !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
117
|
+
requirements:
|
118
|
+
- - ! '>='
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
type: :development
|
122
|
+
prerelease: false
|
123
|
+
version_requirements: *16172960
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: horo
|
126
|
+
requirement: &16171460 !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: *16171460
|
135
|
+
- !ruby/object:Gem::Dependency
|
136
|
+
name: simplecov
|
137
|
+
requirement: &16170380 !ruby/object:Gem::Requirement
|
138
|
+
none: false
|
139
|
+
requirements:
|
140
|
+
- - ! '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: *16170380
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: diesel
|
148
|
+
requirement: &16169260 !ruby/object:Gem::Requirement
|
149
|
+
none: false
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
type: :development
|
155
|
+
prerelease: false
|
156
|
+
version_requirements: *16169260
|
157
|
+
- !ruby/object:Gem::Dependency
|
158
|
+
name: ZenTest
|
159
|
+
requirement: &16167620 !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ! '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
version_requirements: *16167620
|
168
|
+
- !ruby/object:Gem::Dependency
|
169
|
+
name: guard
|
170
|
+
requirement: &16148100 !ruby/object:Gem::Requirement
|
171
|
+
none: false
|
172
|
+
requirements:
|
173
|
+
- - ! '>='
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: *16148100
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: guard-rspec
|
181
|
+
requirement: &16146360 !ruby/object:Gem::Requirement
|
182
|
+
none: false
|
183
|
+
requirements:
|
184
|
+
- - ! '>='
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
type: :development
|
188
|
+
prerelease: false
|
189
|
+
version_requirements: *16146360
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: rb-inotify
|
192
|
+
requirement: &16143520 !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: *16143520
|
201
|
+
- !ruby/object:Gem::Dependency
|
202
|
+
name: libnotify
|
203
|
+
requirement: &16103820 !ruby/object:Gem::Requirement
|
204
|
+
none: false
|
205
|
+
requirements:
|
206
|
+
- - ! '>='
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
type: :development
|
210
|
+
prerelease: false
|
211
|
+
version_requirements: *16103820
|
212
|
+
description: Persist serialization in the model.
|
213
|
+
email:
|
214
|
+
- christopher.meiklejohn@gmail.com
|
215
|
+
executables: []
|
216
|
+
extensions: []
|
217
|
+
extra_rdoc_files: []
|
218
|
+
files:
|
219
|
+
- .gitignore
|
220
|
+
- .rspec
|
221
|
+
- .rvmrc
|
222
|
+
- .travis.yml
|
223
|
+
- Appraisals
|
224
|
+
- Gemfile
|
225
|
+
- Guardfile
|
226
|
+
- LICENSE
|
227
|
+
- README.rdoc
|
228
|
+
- Rakefile
|
229
|
+
- db/schema.rb
|
230
|
+
- gemfiles/rails-3.1.0.gemfile
|
231
|
+
- gemfiles/rails-3.1.0.gemfile.lock
|
232
|
+
- lib/materializer.rb
|
233
|
+
- lib/materializer/base.rb
|
234
|
+
- lib/materializer/core_ext.rb
|
235
|
+
- lib/materializer/version.rb
|
236
|
+
- materializer.gemspec
|
237
|
+
- spec/controllers/garages_controller_spec.rb
|
238
|
+
- spec/database.yml
|
239
|
+
- spec/models/garage_spec.rb
|
240
|
+
- spec/spec_helper.rb
|
241
|
+
- spec/support/controllers.rb
|
242
|
+
- spec/support/factories.rb
|
243
|
+
- spec/support/models.rb
|
244
|
+
- spec/support/routes.rb
|
245
|
+
homepage: https://github.com/cmeiklejohn/materializer
|
246
|
+
licenses: []
|
247
|
+
post_install_message:
|
248
|
+
rdoc_options: []
|
249
|
+
require_paths:
|
250
|
+
- lib
|
251
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
252
|
+
none: false
|
253
|
+
requirements:
|
254
|
+
- - ! '>='
|
255
|
+
- !ruby/object:Gem::Version
|
256
|
+
version: '0'
|
257
|
+
segments:
|
258
|
+
- 0
|
259
|
+
hash: 4326388122469470182
|
260
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
261
|
+
none: false
|
262
|
+
requirements:
|
263
|
+
- - ! '>='
|
264
|
+
- !ruby/object:Gem::Version
|
265
|
+
version: '0'
|
266
|
+
segments:
|
267
|
+
- 0
|
268
|
+
hash: 4326388122469470182
|
269
|
+
requirements: []
|
270
|
+
rubyforge_project: materializer
|
271
|
+
rubygems_version: 1.8.6
|
272
|
+
signing_key:
|
273
|
+
specification_version: 3
|
274
|
+
summary: Persist serialization in the model.
|
275
|
+
test_files: []
|