mongoid_denormalize 0.1.0 → 0.2.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.
- data/README.md +23 -0
- data/lib/mongoid_denormalize.rb +12 -1
- data/lib/railties/denormalize.rake +39 -0
- data/lib/railties/railtie.rb +9 -0
- data/spec/{models → app/models}/comment.rb +0 -0
- data/spec/{models → app/models}/post.rb +0 -0
- data/spec/{models → app/models}/user.rb +0 -0
- data/spec/mongoid_denormalize_spec.rb +26 -3
- data/spec/spec_helper.rb +9 -7
- metadata +9 -19
data/README.md
CHANGED
@@ -3,6 +3,8 @@ Mongoid::Denormalize
|
|
3
3
|
|
4
4
|
Helper module for denormalizing association attributes in Mongoid models. Why denormalize? Read *[A Note on Denormalization](http://www.mongodb.org/display/DOCS/MongoDB+Data+Modeling+and+Rails#MongoDBDataModelingandRails-ANoteonDenormalization)*.
|
5
5
|
|
6
|
+
Extracted from [coookin'](http://coookin.com), where it is used in production.
|
7
|
+
|
6
8
|
|
7
9
|
Installation
|
8
10
|
------------
|
@@ -86,6 +88,27 @@ the parent. When using the `:to` option, the parent will push the values to its
|
|
86
88
|
denormalize :name, :to => [:posts, :comments]
|
87
89
|
|
88
90
|
|
91
|
+
Rake tasks
|
92
|
+
----------
|
93
|
+
|
94
|
+
A rake task is included for verifying and repairing inconsistent denormalizations. This might be useful your records may be modified
|
95
|
+
without Mongoid, or if you are using relational associations in combination with embedded records (see *Known issues*).
|
96
|
+
|
97
|
+
rake db:denormalize
|
98
|
+
|
99
|
+
This task will only update records that have outdated denormalized fields.
|
100
|
+
|
101
|
+
|
102
|
+
Known issues
|
103
|
+
------------
|
104
|
+
|
105
|
+
**Relational associations in combination with embedded records**
|
106
|
+
|
107
|
+
If you are using denormalize with the `:to` option, to denormalize values on a relational association that is embedded in another collection,
|
108
|
+
the denormalized fields will not be updated when the parent record is changed. This is due to a limitation in Mongoid that prevents querying
|
109
|
+
embedded records through relational associations. One way to overcome this issue is to run `rake db:denormalize` in a cron job.
|
110
|
+
|
111
|
+
|
89
112
|
Credits
|
90
113
|
-------
|
91
114
|
|
data/lib/mongoid_denormalize.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/railties/railtie' if defined?(Rails::Railtie)
|
2
|
+
|
1
3
|
# = Mongoid::Denormalize
|
2
4
|
#
|
3
5
|
# Helper module for denormalizing association attributes in Mongoid models.
|
4
6
|
module Mongoid::Denormalize
|
5
7
|
extend ActiveSupport::Concern
|
6
|
-
|
8
|
+
|
7
9
|
included do
|
8
10
|
cattr_accessor :denormalize_definitions
|
9
11
|
|
@@ -36,6 +38,15 @@ module Mongoid::Denormalize
|
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
41
|
+
def denormalized_valid?
|
42
|
+
denormalize_from
|
43
|
+
!self.changed?
|
44
|
+
end
|
45
|
+
|
46
|
+
def repair_denormalized!
|
47
|
+
self.save! unless denormalized_valid?
|
48
|
+
end
|
49
|
+
|
39
50
|
private
|
40
51
|
def denormalize_from
|
41
52
|
self.denormalize_definitions.each do |definition|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
namespace :db do
|
2
|
+
desc "Verify all denormalizations and repair any inconsistencies"
|
3
|
+
task :denormalize => :environment do
|
4
|
+
get_denormalizable_models.each do |klass|
|
5
|
+
if klass.embedded?
|
6
|
+
reflection = klass.reflect_on_all_associations(:embedded_in).first
|
7
|
+
parent = reflection.options[:name].to_s.classify.constantize
|
8
|
+
|
9
|
+
unless parent.embedded?
|
10
|
+
parent.all.each do |parent_instance|
|
11
|
+
parent_instance.send(reflection.options[:inverse_of]).each(&:repair_denormalized!)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
else
|
15
|
+
klass.all.each do |instance|
|
16
|
+
instance.repair_denormalized!
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_denormalizable_models
|
23
|
+
documents = []
|
24
|
+
Dir.glob("app/models/**/*.rb").sort.each do |file|
|
25
|
+
model_path = file[0..-4].split('/')[2..-1]
|
26
|
+
begin
|
27
|
+
klass = model_path.map(&:classify).join('::').constantize
|
28
|
+
|
29
|
+
if klass.ancestors.include?(Mongoid::Document) && klass.ancestors.include?(Mongoid::Denormalize)
|
30
|
+
documents << klass
|
31
|
+
end
|
32
|
+
rescue => e
|
33
|
+
# Just for non-mongoid objects that dont have the embedded
|
34
|
+
# attribute at the class level.
|
35
|
+
end
|
36
|
+
end
|
37
|
+
documents
|
38
|
+
end
|
39
|
+
end
|
File without changes
|
File without changes
|
File without changes
|
@@ -2,9 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Mongoid::Denormalize do
|
4
4
|
before(:all) do
|
5
|
-
Mongoid.master.collections.
|
6
|
-
c.drop rescue nil
|
7
|
-
end
|
5
|
+
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
|
8
6
|
|
9
7
|
@post = Post.create!(:title => "Blog post", :body => "Lorem ipsum...", :created_at => Time.parse("Jan 1 2010 12:00"))
|
10
8
|
@user = User.create!(:name => "John Doe", :email => "john@doe.com", :post => @post)
|
@@ -77,4 +75,29 @@ describe Mongoid::Denormalize do
|
|
77
75
|
@comment.post_created_at.should eql Time.parse("Jan 1 2011 12:00")
|
78
76
|
end
|
79
77
|
end
|
78
|
+
|
79
|
+
context "rake task" do
|
80
|
+
it "should correct inconsistent denormalizations on regular documents" do
|
81
|
+
Post.collection.update({ '_id' => @post.id }, { '$set' => { 'user_name' => 'Clint Eastwood' } })
|
82
|
+
|
83
|
+
Rake::Task["db:denormalize"].invoke
|
84
|
+
Rake::Task["db:denormalize"].reenable
|
85
|
+
|
86
|
+
@post.reload
|
87
|
+
@post.user_name.should eql @user.name
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should correct inconsistent denormalizations on referenced embedded documents" do
|
91
|
+
@rake_user = User.create!(:name => "Johnny Depp", :email => "johnny@depp.com")
|
92
|
+
@rake_comment = @post.comments.create!(:body => "Depp's comment", :user => @rake_user)
|
93
|
+
|
94
|
+
@rake_user.update_attributes!(:name => "J. Depp")
|
95
|
+
|
96
|
+
Rake::Task["db:denormalize"].invoke
|
97
|
+
Rake::Task["db:denormalize"].reenable
|
98
|
+
|
99
|
+
@post.reload
|
100
|
+
@post.comments.last.user_name.should eql @rake_user.name
|
101
|
+
end
|
102
|
+
end
|
80
103
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,15 +2,17 @@ require 'rubygems'
|
|
2
2
|
require 'spec'
|
3
3
|
require 'mongoid'
|
4
4
|
require 'yaml'
|
5
|
+
require 'rake'
|
6
|
+
|
7
|
+
# Load rake tasks
|
8
|
+
load File.expand_path("../../lib/railties/denormalize.rake", __FILE__)
|
9
|
+
task :environment do
|
10
|
+
Dir.chdir(File.dirname(__FILE__))
|
11
|
+
end
|
5
12
|
|
6
13
|
Mongoid.configure do |config|
|
7
|
-
|
8
|
-
|
9
|
-
db = Mongo::Connection.new(settings['host'], settings['port']).db(settings['database'])
|
10
|
-
db.authenticate(settings['username'], settings['password'])
|
11
|
-
|
12
|
-
config.master = db
|
14
|
+
config.master = Mongo::Connection.new.db("mongoid_denormalize_development")
|
13
15
|
end
|
14
16
|
|
15
17
|
require File.expand_path("../../lib/mongoid_denormalize", __FILE__)
|
16
|
-
Dir["#{File.dirname(__FILE__)}/models/*.rb"].each { |f| require f }
|
18
|
+
Dir["#{File.dirname(__FILE__)}/app/models/*.rb"].each { |f| require f }
|
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_denormalize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash: 27
|
5
4
|
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
|
-
-
|
7
|
+
- 2
|
9
8
|
- 0
|
10
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Logan Raarup
|
@@ -15,18 +14,16 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-07
|
17
|
+
date: 2010-09-07 00:00:00 +02:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
name: mongoid
|
23
22
|
prerelease: false
|
24
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
24
|
requirements:
|
27
25
|
- - ~>
|
28
26
|
- !ruby/object:Gem::Version
|
29
|
-
hash: -1848230043
|
30
27
|
segments:
|
31
28
|
- 2
|
32
29
|
- 0
|
@@ -48,11 +45,8 @@ files:
|
|
48
45
|
- LICENSE
|
49
46
|
- README.md
|
50
47
|
- lib/mongoid_denormalize.rb
|
51
|
-
-
|
52
|
-
-
|
53
|
-
- spec/models/user.rb
|
54
|
-
- spec/mongoid_denormalize_spec.rb
|
55
|
-
- spec/spec_helper.rb
|
48
|
+
- lib/railties/denormalize.rake
|
49
|
+
- lib/railties/railtie.rb
|
56
50
|
has_rdoc: true
|
57
51
|
homepage: http://github.com/logandk/mongoid_denormalize
|
58
52
|
licenses: []
|
@@ -63,33 +57,29 @@ rdoc_options:
|
|
63
57
|
require_paths:
|
64
58
|
- lib
|
65
59
|
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
60
|
requirements:
|
68
61
|
- - ">="
|
69
62
|
- !ruby/object:Gem::Version
|
70
|
-
hash: 3
|
71
63
|
segments:
|
72
64
|
- 0
|
73
65
|
version: "0"
|
74
66
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
-
none: false
|
76
67
|
requirements:
|
77
68
|
- - ">="
|
78
69
|
- !ruby/object:Gem::Version
|
79
|
-
hash: 3
|
80
70
|
segments:
|
81
71
|
- 0
|
82
72
|
version: "0"
|
83
73
|
requirements: []
|
84
74
|
|
85
75
|
rubyforge_project:
|
86
|
-
rubygems_version: 1.3.
|
76
|
+
rubygems_version: 1.3.6
|
87
77
|
signing_key:
|
88
78
|
specification_version: 3
|
89
79
|
summary: Mongoid denormalization helper.
|
90
80
|
test_files:
|
91
|
-
- spec/models/comment.rb
|
92
|
-
- spec/models/post.rb
|
93
|
-
- spec/models/user.rb
|
81
|
+
- spec/app/models/comment.rb
|
82
|
+
- spec/app/models/post.rb
|
83
|
+
- spec/app/models/user.rb
|
94
84
|
- spec/mongoid_denormalize_spec.rb
|
95
85
|
- spec/spec_helper.rb
|