mongoblazer 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
data/Rakefile CHANGED
@@ -1 +1,5 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ task :default do
4
+ exit system('bundle exec rspec spec --color --debug')
5
+ end
@@ -1,5 +1,11 @@
1
+ require "rails"
2
+ require "mongoid"
3
+ require "active_record"
1
4
  require "mongoblazer/version"
5
+ require "mongoblazer/active_record/carrierwave"
6
+ require "mongoblazer/active_record"
7
+ require "mongoblazer/document"
8
+ require "mongoblazer/railtie"
2
9
 
3
10
  module Mongoblazer
4
- # Your code goes here...
5
11
  end
@@ -0,0 +1,431 @@
1
+ module Mongoblazer
2
+ ##
3
+ # Mongoblazer's ActiveRecord extension.
4
+ #
5
+ module ActiveRecord
6
+ extend ActiveSupport::Concern
7
+ include Carrierwave
8
+
9
+ included do
10
+ def mongoblazed
11
+ @mongoblazed ||= begin
12
+ self.class.recreate_mongoblazer_class!
13
+ self.class.mongoblazer_class.where(id: self.mongoblazer_id).last
14
+ end
15
+ end
16
+
17
+ def mongoblazed_add_attribute(name, data={})
18
+ self.class.recreate_mongoblazer_class!
19
+ instance = self.class.mongoblazer_class.where(id: self.mongoblazer_id).last
20
+ instance[name] = data
21
+ instance.save!
22
+ @mongoblazed = instance
23
+ end
24
+
25
+ ##
26
+ # Add a relation that is not in the includes options
27
+ #
28
+ # Example:
29
+ # post.mongoblazed.add_include(:comments, post.comments.map(&:attributes))
30
+ #
31
+ # Returns the mongoblazed instance with the new include.
32
+ def mongoblazed_add_include(name, data={})
33
+ self.class.recreate_mongoblazer_class!
34
+ relations = {name => data}
35
+ mongoblaze_relations(mongoblazed, relations)
36
+ mongoblazed.save!
37
+ mongoblazed
38
+ end
39
+
40
+ def mongoblaze!(caller=self.class)
41
+ if @mongoblazer_already_blazing
42
+ @mongoblazer_already_blazing = false
43
+ return true
44
+ end
45
+
46
+ self.class.recreate_mongoblazer_class!
47
+
48
+ data = mongoblazer_attributes
49
+ relations = {}
50
+
51
+ self.class.mongoblazer_options[:embeds_one].each do |em, class_name|
52
+ if related = data.delete(em)
53
+ klass = class_name ? class_name.constantize : "#{em.to_s.camelize}".constantize
54
+ if klass != caller
55
+ related_id = related['id'] || data["#{em}_id"]
56
+ if klass.mongoblazable? && related_id
57
+ klass.recreate_mongoblazer_class!
58
+ relations[em] = klass.find(related_id).mongoblazer_attributes(self.class)
59
+ else
60
+ data[em] = related.attributes
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ self.class.mongoblazer_options[:embeds_many].each do |em, class_name|
67
+ if related = data.delete(em)
68
+ klass = class_name ? class_name.constantize : "#{em.to_s.singularize.camelize}".constantize
69
+ if klass != caller
70
+ if klass.mongoblazable?
71
+ klass.recreate_mongoblazer_class!
72
+ relations[em] = related.map do |r|
73
+ related_id = r['id'] || data["#{em.to_s.singularize}_id"]
74
+ if related_id
75
+ klass.find(related_id).mongoblazer_attributes(self.class)
76
+ else
77
+ r.attributes
78
+ end
79
+ end
80
+ else
81
+ data[em] = related.map(&:attributes)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ self.class.recreate_mongoblazer_class!
88
+
89
+ blazed_record = if self.mongoblazer_id.present?
90
+ self.class.mongoblazer_class
91
+ .where(id: self.mongoblazer_id).first
92
+ else
93
+ nil
94
+ end
95
+
96
+ if blazed_record.present?
97
+ blazed_record.save!(data)
98
+ else
99
+ blazed_record = self.class.mongoblazer_class.create(data)
100
+ @mongoblazer_already_blazing = true
101
+ update_attribute :mongoblazer_id, blazed_record.id.to_s
102
+ end
103
+
104
+ mongoblaze_relations(blazed_record, relations)
105
+
106
+ blazed_record.save!
107
+
108
+ blazed_record
109
+ end
110
+
111
+ def mongoblaze_relations(blazed_record, relations)
112
+ if relations.present?
113
+ self.class.recreate_mongoblazer_class!
114
+
115
+ relations.each do |name, related|
116
+ next if self.class.mongoblazer_options[:uploaders].include? name
117
+
118
+ if related.is_a? Array
119
+ blazed_record.send(name).destroy_all
120
+
121
+ related.each do |r|
122
+ blazed_record.send(name).build(r)
123
+ end
124
+
125
+ else
126
+ blazed_record.send("build_#{name}", related)
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ def mongoblazer_attributes(caller=self.class)
133
+ if self.class.mongoblazable?
134
+ self.class.recreate_mongoblazer_class!
135
+
136
+ includes = self.class.mongoblazer_options[:includes]
137
+
138
+ instance = self.class.includes(includes).find(id)
139
+ data = if includes
140
+ instance.serializable_hash(:include => includes)
141
+ else
142
+ instance.attributes
143
+ end
144
+
145
+ if additional = self.class.mongoblazer_options[:additional_attributes]
146
+ additional.each do |attribute|
147
+ next if self.class.mongoblazer_options[:uploaders].include? attribute
148
+
149
+ data[attribute] = instance.send(attribute)
150
+ end
151
+ end
152
+
153
+ if uploaders = self.class.mongoblazer_options[:uploaders]
154
+ uploaders.each do |uploader|
155
+ data.delete(uploader)
156
+ data.delete(uploader.to_s)
157
+ if instance.send(uploader).present?
158
+ versions = {}
159
+ instance.send(uploader).versions.each do |v,u|
160
+ versions[v] = u.to_s
161
+ end
162
+ versions.merge({default: instance.send(uploader).to_s})
163
+ end
164
+ end
165
+ end
166
+
167
+ data[:ar_id] = data.delete('id')
168
+
169
+ data.delete(caller.name.underscore.to_sym)
170
+ data.delete(caller.name.pluralize.underscore.to_sym)
171
+
172
+ self.class.recreate_mongoblazer_class!
173
+
174
+ data
175
+ else
176
+ throw "#{self.class.name} is not Mongoblazable!"
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ # Add associations specified via the <tt>:include</tt> option.
183
+ #
184
+ # Expects a block that takes as arguments:
185
+ # +association+ - name of the association
186
+ # +records+ - the association record(s) to be serialized
187
+ # +opts+ - options for the association records
188
+ def serializable_add_includes(options = {}) #:nodoc:
189
+ return unless include = options[:include]
190
+
191
+ unless include.is_a?(Hash)
192
+ include = Hash[Array.wrap(include).map { |n| n.is_a?(Hash) ? n.to_a.first : [n, {}] }]
193
+ end
194
+
195
+ include.each do |association, opts|
196
+ # TODO: This is broken in Rails 3.2.13 it seems, hence this fix.
197
+ opts = {:include => opts} if opts.is_a? Array
198
+
199
+ if records = send(association)
200
+ yield association, records, opts
201
+ end
202
+ end
203
+ end
204
+ end
205
+
206
+ module ClassMethods
207
+ def find_blazed(id)
208
+ ar_instance = select("#{self.table_name}.mongoblazer_id").find(id)
209
+
210
+ recreate_mongoblazer_class!
211
+
212
+ mongoblazer_class.find(ar_instance.mongoblazer_id)
213
+ end
214
+
215
+ ##
216
+ # Is this model Mongoblazable?
217
+ #
218
+ def mongoblazable?
219
+ mongoblazer_options.present?
220
+ end
221
+
222
+ def belongs_to(name, options={})
223
+ mongoblazer_init embeds_one: {name => options[:class_name]}
224
+ super
225
+ end
226
+
227
+ def has_one(name, options={})
228
+ mongoblazer_init embeds_one: {name => options[:class_name]}
229
+ super
230
+ end
231
+
232
+ def has_many(name, options={})
233
+ mongoblazer_init embeds_many: {name => options[:class_name]}
234
+ super
235
+ end
236
+
237
+ def has_and_belongs_to_many(name, options={})
238
+ mongoblazer_init embeds_many: {name => options[:class_name]}
239
+ super
240
+ end
241
+
242
+ ##
243
+ # Defines relation includes to be merged
244
+ # in the mongodb document.
245
+ #
246
+ # Syntax same as eager loading syntax in AR:
247
+ # http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
248
+ #
249
+ def mongoblazer_includes(options={})
250
+ mongoblazer_init includes: options
251
+ end
252
+
253
+ ##
254
+ # Defines default scope to find the matching mongodb
255
+ # document.
256
+ #
257
+ # Syntax same as where() in AR
258
+ #
259
+ def mongoblazer_default_scope(options={})
260
+ mongoblazer_init default_scope: options
261
+ end
262
+
263
+ ##
264
+ # Defines indexes on the blazer model.
265
+ #
266
+ def mongoblazer_index_fields(options={})
267
+ mongoblazer_init indexes: options
268
+ end
269
+
270
+ ##
271
+ # Defines additional attributes (e.g. not in db) to be merged
272
+ # in the mongodb document.
273
+ #
274
+ def mongoblazer_additional_attributes(options={})
275
+ mongoblazer_init additional_attributes: options
276
+ end
277
+
278
+ ##
279
+ # Initialize Mongoblazer wit some options:
280
+ # includes: relations to include
281
+ # default_scope: the default scope for the blazed model
282
+ # indexes: fields to index in the blazed model
283
+ # embeds_one: model to embed one of
284
+ # embeds_many: model to embed many of
285
+ #
286
+ def mongoblazer_init(options)
287
+ unless @mongoblazer_options
288
+ @mongoblazer_options = {}
289
+
290
+ @mongoblazer_options[:indexes] =
291
+ ::ActiveRecord::Base.connection.indexes(self.table_name).map do |ind|
292
+ {ind => 1}
293
+ end
294
+
295
+ @mongoblazer_options[:uploaders] = []
296
+
297
+ @mongoblazer_options[:embeds_one] = {}
298
+ @mongoblazer_options[:embeds_many] = {}
299
+ end
300
+
301
+ if one = options.delete(:embeds_one)
302
+ @mongoblazer_options[:embeds_one][one.keys.first] = one.values.first
303
+ end
304
+
305
+ if many = options.delete(:embeds_many)
306
+ @mongoblazer_options[:embeds_many][many.keys.first] = many.values.first
307
+ end
308
+
309
+ if uploader = options.delete(:uploaders)
310
+ @mongoblazer_options[:uploaders] << uploader
311
+ end
312
+
313
+ @mongoblazer_options.merge! options
314
+
315
+ create_mongoblazer_class!
316
+ end
317
+
318
+ def mongoblazer_options
319
+ if defined?(@mongoblazer_options)
320
+ @mongoblazer_options
321
+ elsif superclass.respond_to?(:mongoblazer_options)
322
+ superclass.mongoblazer_options || { }
323
+ else
324
+ { }
325
+ end
326
+ end
327
+
328
+ def mongoblazer_class
329
+ mongoblazer_class_name.constantize
330
+ end
331
+
332
+ def mongoblazer_class_name
333
+ "#{self.name}Blazer"
334
+ end
335
+
336
+ def recreate_mongoblazer_class!(called_from_parent=false)
337
+ create_mongoblazer_class!
338
+
339
+ unless called_from_parent
340
+ begin
341
+ configuration[:embeds_one].each do |rel|
342
+ "#{rel.to_s.camelize}".constantize.recreate_mongoblazer_class!(true)
343
+ end
344
+ rescue NameError
345
+ end
346
+ begin
347
+ configuration[:embeds_many].each do |rel|
348
+ "#{rel.to_s.singularize.camelize}".constantize.recreate_mongoblazer_class!(true)
349
+ end
350
+ rescue NameError
351
+ end
352
+ end
353
+ end
354
+
355
+ private # ----------------------------------------------------------------
356
+
357
+ def create_mongoblazer_class!
358
+ configuration = mongoblazer_options
359
+
360
+ relations = configure_mongoblazer_relations! configuration[:embeds_one], :embeds_one
361
+ relations += configure_mongoblazer_relations! configuration[:embeds_many], :embeds_many
362
+
363
+ uploaders = configure_mongoblazer_uploaders!
364
+
365
+ klass = begin
366
+ mongoblazer_class
367
+ rescue NameError
368
+ collection = mongoblazer_class_name.pluralize.underscore
369
+
370
+ klass = Class.new do
371
+ include ::Mongoblazer::Document
372
+
373
+ # Use one collection to avoid class initialization trouble
374
+ # when guessing the collection to use.
375
+ store_in collection: collection
376
+
377
+ index ar_id: 1
378
+ index _type: 1
379
+
380
+ default_scope configuration[:default_scope] if configuration[:default_scope].present?
381
+
382
+ configuration[:indexes].each { |ind| index ind }
383
+ end
384
+
385
+ Object.const_set mongoblazer_class_name, klass
386
+
387
+ klass
388
+ end
389
+
390
+ klass.module_eval relations.join("\n")
391
+ klass.module_eval uploaders.join("\n")
392
+ end
393
+
394
+ def configure_mongoblazer_relations!(relations, embed_type=:embeds_one)
395
+ relations.map do |em, klass_name|
396
+ class_name = if klass_name
397
+ "#{klass_name}Blazer"
398
+ elsif embed_type == :embeds_one
399
+ "#{em.to_s.camelize}Blazer"
400
+ else
401
+ "#{em.to_s.singularize.camelize}Blazer"
402
+ end
403
+
404
+ if const_defined?(class_name)
405
+ <<-CODE
406
+ #{embed_type} :#{em}, class_name: '#{class_name}', inverse_of: '#{mongoblazer_class_name}'
407
+ accepts_nested_attributes_for :#{em}
408
+ CODE
409
+ else
410
+ <<-CODE
411
+ def #{em}=(data)
412
+ write_attribute(:#{em}, data)
413
+ end
414
+
415
+ def #{em}
416
+ data = attributes['#{em}']
417
+ if data.is_a? Array
418
+ data.map{|d| OpenStruct.new(d)}
419
+ elsif data.is_a? Hash
420
+ OpenStruct.new(data)
421
+ else
422
+ data
423
+ end
424
+ end
425
+ CODE
426
+ end
427
+ end
428
+ end
429
+ end
430
+ end
431
+ end
@@ -0,0 +1,47 @@
1
+ # module CarrierWave
2
+ # class Uploader::Base
3
+ # def __bson_dump__(io, key)
4
+ # data = versions.merge({default: self.to_s})
5
+
6
+ # io << Types::OBJECT_ID
7
+ # io << key
8
+ # io << NULL_BYTE
9
+ # io << data
10
+ # end
11
+ # end
12
+ # end
13
+
14
+ module Mongoblazer
15
+ module ActiveRecord
16
+ module Carrierwave
17
+ extend ActiveSupport::Concern
18
+
19
+ module ClassMethods
20
+ def mount_uploader(name, klass, options={})
21
+ mongoblazer_init uploaders: name
22
+ super
23
+ end
24
+
25
+ private
26
+
27
+ def configure_mongoblazer_uploaders!
28
+ mongoblazer_options[:uploaders].map do |uploader|
29
+ <<-CODE
30
+ def #{uploader}
31
+ @#{uploader} ||= begin
32
+ klass = Class.new OpenStruct do
33
+ def to_s
34
+ default
35
+ end
36
+ end
37
+
38
+ klass.new(attributes['#{uploader}'])
39
+ end
40
+ end
41
+ CODE
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ module Mongoblazer
2
+ module Document
3
+ extend ActiveSupport::Concern
4
+ include Mongoid::Document
5
+
6
+ included do
7
+ field :ar_id, type: String
8
+
9
+ index ar_id: 1
10
+
11
+ def is_mongoblazed?
12
+ true
13
+ end
14
+
15
+ def ar_object
16
+ @ar_object ||= self.class.name.sub(/Blazer$/, '').constantize.find(ar_id)
17
+ end
18
+
19
+ def method_missing(method_sym, *arguments, &block)
20
+ begin
21
+ super
22
+ rescue NoMethodError
23
+ Rails.logger.debug "MONGOBLAZER DEBUG: #{self.class.name} access to unblazed method:
24
+ #{method_sym} with args:
25
+ #{arguments.inspect}
26
+ for record with id: #{id}"
27
+ if ar_object.respond_to? method_sym
28
+ ar_object.send method_sym
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ module Mongoblazer
2
+ if defined? Rails::Railtie
3
+ require 'rails'
4
+
5
+ class Railtie < Rails::Railtie
6
+ initializer 'mongoblazer.insert_into_active_record' do
7
+ ActiveSupport.on_load :active_record do
8
+ Mongoblazer::Railtie.insert
9
+ end
10
+ end
11
+
12
+ # rake_tasks do
13
+ # load "tasks/mongoblazer.rake"
14
+ # end
15
+ end
16
+ end
17
+
18
+ class Railtie
19
+ def self.insert
20
+ if defined?(::ActiveRecord)
21
+ ::ActiveRecord::Base.class_eval do
22
+ include Mongoblazer::ActiveRecord
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Mongoblazer
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -20,6 +20,10 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
22
  spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "database_cleaner"
25
+ spec.add_development_dependency "debugger"
26
+ spec.add_development_dependency "sqlite3"
23
27
 
24
28
  spec.add_runtime_dependency "rails"
25
29
  spec.add_runtime_dependency "mongoid"
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongoblazer::ActiveRecord do
4
+
5
+ describe ".mongoblazable" do
6
+ context "not enabled" do
7
+ subject { NotEnabled }
8
+ it { should_not be_mongoblazable }
9
+ end
10
+
11
+ context "enabled" do
12
+ subject { Enabled }
13
+ it { should be_mongoblazable }
14
+ end
15
+
16
+ context "enabled in parent" do
17
+ subject { EnabledInParent }
18
+ it { should be_mongoblazable }
19
+ end
20
+
21
+ context "options" do
22
+ subject { EnabledInParent.mongoblazer_options }
23
+ it { should eq({:indexes=>[], :uploaders=>[], :embeds_one=>{}, :embeds_many=>{:posts=>nil}, :includes=>{:posts=>[{:comments=>:user}, :tags]}, :additional_attributes=>[:additional]}) }
24
+ end
25
+ end
26
+
27
+ describe ".create_mongoblazer_class!" do
28
+ subject { Enabled }
29
+
30
+ it "should have defined the EnabledBlazer class" do
31
+ defined?(EnabledBlazer).should eq "constant"
32
+ end
33
+ end
34
+
35
+ describe ".mongoblaze!" do
36
+ let(:post) { Post.create(title: "Foo", body: "Bar baz burp", status: 'published')}
37
+ let(:enabled) { Enabled.create(name: "Enabled", posts: [post]) }
38
+
39
+ context "after_create" do
40
+ before { Enabled.any_instance.should_receive :mongoblaze! }
41
+
42
+ it { enabled }
43
+ end
44
+
45
+ context "with relations" do
46
+ subject { enabled.mongoblazed }
47
+
48
+ it "should contain a post" do
49
+ subject.posts.size.should be 1
50
+ end
51
+
52
+ context "related data" do
53
+ subject { enabled.mongoblazed.posts.first }
54
+
55
+ its(:title) { should eq "Foo" }
56
+ its(:body) { should eq "Bar baz burp" }
57
+ its(:status) { should eq "published" }
58
+ end
59
+
60
+ context "with additional_attributes" do
61
+ its(:additional) { should eq "additional attribute to include" }
62
+ end
63
+
64
+ context "with attributes not in blazed fallback" do
65
+ its(:not_in_blazed) { should eq "this is not in the blazed instance" }
66
+ end
67
+ end
68
+
69
+ context "with enabled relations" do
70
+ let(:enabled) { WithEnabledRelation.create(name: "FooBar", related_enableds: [related_enabled]) }
71
+ let(:related_enabled) { RelatedEnabled.create(name: "Related To FooBar") }
72
+ subject { enabled.mongoblazed }
73
+
74
+ its(:name) { should eq "FooBar" }
75
+
76
+ it "should have embedded related_enableds" do
77
+ subject.related_enableds.size.should be 1
78
+ end
79
+
80
+ context "options" do
81
+ subject { WithEnabledRelation.mongoblazer_options }
82
+ it { should eq({:indexes=>[], :uploaders=>[], :embeds_one=>{}, :embeds_many=>{:related_enableds=>nil}, :includes=>:related_enableds}) }
83
+ end
84
+
85
+ context "relations" do
86
+ subject { enabled.mongoblazed.related_enableds.first }
87
+
88
+ its(:name) { should eq "Related To FooBar" }
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,14 @@
1
+ ENV["RACK_ENV"] ||= 'test'
2
+ ENV['RAILS_ENV'] ||= 'test'
3
+
4
+ require 'bundler'
5
+ Bundler.require
6
+
7
+ Dir[File.expand_path("../../lib/**/*.rb", __FILE__)].each {|f| require f}
8
+ Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+ config.color_enabled = true
12
+ config.tty = true
13
+ config.formatter = :progress
14
+ end
@@ -0,0 +1,121 @@
1
+ ::ActiveRecord::Base.class_eval do
2
+ include Mongoblazer::ActiveRecord
3
+ end
4
+
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => 'sqlite3',
7
+ :database => ':memory:'
8
+ )
9
+
10
+ ActiveRecord::Schema.define(:version => 0) do
11
+ create_table "not_enableds" do |t|
12
+ t.string "name"
13
+ end
14
+
15
+ create_table "enableds" do |t|
16
+ t.string "name"
17
+ t.string "mongoblazer_id"
18
+ end
19
+
20
+ create_table "with_enabled_relations" do |t|
21
+ t.string "name"
22
+ t.string "mongoblazer_id"
23
+ end
24
+
25
+ create_table "related_enableds" do |t|
26
+ t.string "name"
27
+ t.integer "with_enabled_relation_id"
28
+ end
29
+
30
+ create_table "posts" do |t|
31
+ t.integer "enabled_id"
32
+ t.integer "user_id"
33
+ t.string "title"
34
+ t.text "body"
35
+ t.string "status"
36
+ end
37
+
38
+ add_index "posts", "status", name: "index_posts_on_status"
39
+
40
+ create_table "comments" do |t|
41
+ t.integer "post_id"
42
+ t.integer "user_id"
43
+ t.string "text"
44
+ end
45
+
46
+ create_table "users" do |t|
47
+ t.string "name"
48
+ end
49
+
50
+ create_table "tags" do |t|
51
+ t.string "name"
52
+ end
53
+
54
+ create_table "posts_tags", id: false do |t|
55
+ t.integer "post_id"
56
+ t.integer "tag_id"
57
+ end
58
+ end
59
+
60
+ class NotEnabled < ActiveRecord::Base
61
+ end
62
+
63
+ class Enabled < ActiveRecord::Base
64
+ has_many :posts
65
+
66
+ mongoblazer_includes posts: [{comments: :user}, :tags]
67
+ mongoblazer_additional_attributes [:additional]
68
+
69
+ after_save :mongoblaze!
70
+
71
+ def additional
72
+ "additional attribute to include"
73
+ end
74
+
75
+ def not_in_blazed
76
+ "this is not in the blazed instance"
77
+ end
78
+ end
79
+
80
+ class EnabledInParent < Enabled
81
+ end
82
+
83
+ class WithEnabledRelation < ActiveRecord::Base
84
+ has_many :related_enableds
85
+
86
+ mongoblazer_includes :related_enableds
87
+
88
+ after_save :mongoblaze!
89
+ end
90
+
91
+ class RelatedEnabled < ActiveRecord::Base
92
+ belongs_to :with_enabled_relation
93
+
94
+ mongoblazer_includes :with_enabled_relation
95
+ end
96
+
97
+ class DefaultScoped < Enabled
98
+ default_scope where(foo: "bar")
99
+ end
100
+
101
+ class Post < ActiveRecord::Base
102
+ belongs_to :user
103
+ has_many :comments
104
+ has_and_belongs_to_many :tags
105
+
106
+ default_scope where(status: 'published')
107
+ end
108
+
109
+ class Comment < ActiveRecord::Base
110
+ belongs_to :post
111
+ belongs_to :user
112
+ end
113
+
114
+ class User < ActiveRecord::Base
115
+ has_many :posts
116
+ has_many :comments
117
+ end
118
+
119
+ class Tag < ActiveRecord::Base
120
+ has_and_belongs_to_many :posts
121
+ end
@@ -0,0 +1,20 @@
1
+ require 'database_cleaner'
2
+
3
+ RSpec.configure do |config|
4
+
5
+ config.before :suite do
6
+ DatabaseCleaner.orm = :mongoid
7
+ DatabaseCleaner.strategy = :truncation
8
+ DatabaseCleaner.clean_with :truncation
9
+ end
10
+
11
+ config.before :each do
12
+ DatabaseCleaner.clean
13
+ DatabaseCleaner.start
14
+ end
15
+
16
+ config.after :each do
17
+ DatabaseCleaner.clean
18
+ end
19
+
20
+ end
@@ -0,0 +1 @@
1
+ Mongoid.load!(File.expand_path("../mongoid.yml", __FILE__))
@@ -0,0 +1,6 @@
1
+ test:
2
+ sessions:
3
+ default:
4
+ hosts:
5
+ - <%= ENV['WERCKER'] ? "#{ENV['WERCKER_MONGODB_HOST']}:#{ENV['WERCKER_MONGODB_PORT']}" : "localhost:27017" %>
6
+ database: mongoblazer_test
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoblazer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-04-05 00:00:00.000000000 Z
12
+ date: 2013-04-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -43,6 +43,70 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: database_cleaner
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: debugger
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: sqlite3
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
46
110
  - !ruby/object:Gem::Dependency
47
111
  name: rails
48
112
  requirement: !ruby/object:Gem::Requirement
@@ -89,8 +153,18 @@ files:
89
153
  - README.md
90
154
  - Rakefile
91
155
  - lib/mongoblazer.rb
156
+ - lib/mongoblazer/active_record.rb
157
+ - lib/mongoblazer/active_record/carrierwave.rb
158
+ - lib/mongoblazer/document.rb
159
+ - lib/mongoblazer/railtie.rb
92
160
  - lib/mongoblazer/version.rb
93
161
  - mongoblazer.gemspec
162
+ - spec/mongoblazer/active_record_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/support/ar.rb
165
+ - spec/support/database_cleaner.rb
166
+ - spec/support/mongoid.rb
167
+ - spec/support/mongoid.yml
94
168
  homepage: http://springest.github.com/mongoblazer
95
169
  licenses:
96
170
  - MIT
@@ -116,4 +190,10 @@ rubygems_version: 1.8.23
116
190
  signing_key:
117
191
  specification_version: 3
118
192
  summary: MongoBlazer to flatten ActiveRecord Models into Mongodb Documents
119
- test_files: []
193
+ test_files:
194
+ - spec/mongoblazer/active_record_spec.rb
195
+ - spec/spec_helper.rb
196
+ - spec/support/ar.rb
197
+ - spec/support/database_cleaner.rb
198
+ - spec/support/mongoid.rb
199
+ - spec/support/mongoid.yml