mongoid_denormalize 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
 
@@ -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
@@ -0,0 +1,9 @@
1
+ require 'rails'
2
+
3
+ module Mongoid::Denormalize
4
+ class Railtie < Rails::Railtie
5
+ rake_tasks do
6
+ load 'railties/denormalize.rake'
7
+ end
8
+ end
9
+ 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.each do |c|
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
- settings = YAML.load(File.read(File.join(File.dirname(__FILE__), "database.yml")))
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
- - 1
7
+ - 2
9
8
  - 0
10
- version: 0.1.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-09 00:00:00 +02:00
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
- - spec/models/comment.rb
52
- - spec/models/post.rb
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.7
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