mongoid_denormalize 0.3.0 → 0.4.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 +40 -10
- data/lib/mongoid_denormalize.rb +62 -42
- metadata +118 -48
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
Mongoid::Denormalize
|
2
2
|
====================
|
3
3
|
|
4
|
+
*Note: I am no longer actively maintaining this module, and I do not know whether it is compatible with newer versions of mongoid. If you would like to take ownership of this repository, please let me know.*
|
5
|
+
|
6
|
+
|
4
7
|
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
8
|
|
6
9
|
Extracted from [coookin'](http://coookin.com), where it is used in production.
|
@@ -30,7 +33,6 @@ In your model:
|
|
30
33
|
denormalize :name, :email, :from => :user
|
31
34
|
|
32
35
|
|
33
|
-
|
34
36
|
Example
|
35
37
|
-------
|
36
38
|
|
@@ -39,6 +41,7 @@ Example
|
|
39
41
|
include Mongoid::Denormalize
|
40
42
|
|
41
43
|
has_many :comments
|
44
|
+
has_many :moderated_comments, :class_name => "Comment", :inverse_of => :moderator
|
42
45
|
|
43
46
|
field :name
|
44
47
|
field :email
|
@@ -51,6 +54,7 @@ Example
|
|
51
54
|
include Mongoid::Denormalize
|
52
55
|
|
53
56
|
belongs_to :user
|
57
|
+
belongs_to :moderator, :class_name => "User", :inverse_of => :moderated_comments
|
54
58
|
|
55
59
|
field :body
|
56
60
|
|
@@ -75,20 +79,31 @@ Options
|
|
75
79
|
Denormalization can happen in either or both directions. When using the `:from` option, the associated objects will fetch the values from
|
76
80
|
the parent. When using the `:to` option, the parent will push the values to its children.
|
77
81
|
|
82
|
+
# Basic denormalization. Will set the user_name attribute of "self.comments" to the value of "self.name".
|
83
|
+
denormalize :name, :to => :comments
|
84
|
+
|
85
|
+
# Multiple children. Will set the user_name attribute of "self.posts" and "self.comments" with "self.name".
|
86
|
+
denormalize :name, :to => [:posts, :comments]
|
87
|
+
|
88
|
+
# Basic denormalization, obeying :inverse_of. Will set the moderator_name attribute of "self.moderated_comments"
|
89
|
+
denormalize :name, :email, :to => :moderated_comments
|
90
|
+
|
91
|
+
# With custom field name prefix. Will set the commenter_name attribute of "self.comments" (takes precedence over
|
92
|
+
# inverse_of).
|
93
|
+
denormalize :name, :to => :comments, :as => :commenter
|
94
|
+
|
78
95
|
# Basic denormalization. Will set the user_name attribute with the associated user's name.
|
79
96
|
denormalize :name, :from => :user
|
80
|
-
|
81
|
-
# Basic denormalization. Will set the user_name attribute of "self.comments" with "self.name".
|
82
|
-
denormalize :name, :to => :comments
|
83
|
-
|
97
|
+
|
84
98
|
# Multiple fields. Will set the user_name and user_email attributes with the associated user's name and email.
|
85
99
|
denormalize :name, :email, :from => :user
|
86
|
-
|
87
|
-
# Multiple children. Will set the user_name attribute of "self.posts" and "self.comments" with "self.name".
|
88
|
-
denormalize :name, :to => [:posts, :comments]
|
89
100
|
|
90
|
-
|
91
|
-
|
101
|
+
# Basic denormalization. Will set the moderator_name attribute with the associated author user's name.
|
102
|
+
denormalize :name, :from => :moderator
|
103
|
+
|
104
|
+
When using `:from`, if the type of the denormalized field is anything but `String` (the default),
|
105
|
+
you must specify the type with the `:type` option.
|
106
|
+
|
92
107
|
# in User
|
93
108
|
field :location, :type => Array
|
94
109
|
denormalize :location, :to => :posts
|
@@ -96,6 +111,14 @@ You must specify the type of all denormalizations when using the `:from` option,
|
|
96
111
|
# in Post
|
97
112
|
denormalize :location, :type => Array, :from => :user
|
98
113
|
|
114
|
+
A few notes on behavior:
|
115
|
+
|
116
|
+
`:from` denormalizations are processed as `before_save` callbacks.
|
117
|
+
|
118
|
+
`:to` denormalizations are processed as `after_save` callbacks.
|
119
|
+
|
120
|
+
With `:to`, validations are not run on the object(s) containing the denormalized field(s) when they are saved.
|
121
|
+
|
99
122
|
Rake tasks
|
100
123
|
----------
|
101
124
|
|
@@ -117,12 +140,19 @@ It is not recommended nor supported to use mongoid_denormalize to perform denorm
|
|
117
140
|
|
118
141
|
So, if User has_many :posts and User has_many :comments, but Comments are embedded_in :post, a user can't directly access a comment.
|
119
142
|
|
143
|
+
Contributing
|
144
|
+
-------
|
145
|
+
|
146
|
+
Clone the repository and run Bundler with `bundle install` so that you can run the rake tasks.
|
120
147
|
|
121
148
|
Contributors
|
122
149
|
-------
|
123
150
|
* hubsmoke (https://github.com/hubsmoke)
|
124
151
|
* Leo Lou (https://github.com/l4u)
|
125
152
|
* Austin Bales (https://github.com/arbales)
|
153
|
+
* Isaac Cambron (https://github.com/icambron)
|
154
|
+
* Shannon Carey (https://github.com/rehevkor5)
|
155
|
+
* Sebastien Azimi (https://github.com/suruja)
|
126
156
|
|
127
157
|
|
128
158
|
Credits
|
data/lib/mongoid_denormalize.rb
CHANGED
@@ -5,10 +5,10 @@ require File.dirname(__FILE__) + '/railties/railtie' if defined?(Rails::Railtie)
|
|
5
5
|
# Helper module for denormalizing association attributes in Mongoid models.
|
6
6
|
module Mongoid::Denormalize
|
7
7
|
extend ActiveSupport::Concern
|
8
|
-
|
8
|
+
|
9
9
|
included do
|
10
10
|
cattr_accessor :denormalize_definitions
|
11
|
-
|
11
|
+
|
12
12
|
before_save :denormalize_from
|
13
13
|
after_save :denormalize_to
|
14
14
|
end
|
@@ -26,8 +26,8 @@ module Mongoid::Denormalize
|
|
26
26
|
# denormalize :name, :avatar, :from => :user
|
27
27
|
# denormalize :created_at, :to => :comments
|
28
28
|
# end
|
29
|
-
def denormalize(*
|
30
|
-
options =
|
29
|
+
def denormalize(*args)
|
30
|
+
*fields, options = args
|
31
31
|
|
32
32
|
(self.denormalize_definitions ||= []) << { :fields => fields, :options => options }
|
33
33
|
|
@@ -36,7 +36,7 @@ module Mongoid::Denormalize
|
|
36
36
|
fields.each { |name| field "#{options[:from]}_#{name}", :type => options[:type] || String }
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def is_denormalized?
|
41
41
|
true
|
42
42
|
end
|
@@ -50,49 +50,69 @@ module Mongoid::Denormalize
|
|
50
50
|
def repair_denormalized!
|
51
51
|
self.save! unless denormalized_valid?
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
private
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
def denormalize_from
|
56
|
+
Array(self.denormalize_definitions).reject do |definition|
|
57
|
+
definition[:options][:to]
|
58
|
+
end.each do |definition|
|
59
|
+
definition[:fields].each do |name|
|
60
|
+
field = definition[:options][:from]
|
61
|
+
# force reload if :from method is an association ; call it normally otherwise
|
62
|
+
associated = self.class.reflect_on_association(field) ? self.send(field, true) : self.send(field)
|
63
|
+
self.send("#{field}_#{name}=", associated.try(name))
|
60
64
|
end
|
61
65
|
end
|
62
|
-
|
63
|
-
def denormalize_to
|
64
|
-
self.denormalize_definitions.each do |definition|
|
65
|
-
next unless definition[:options][:to]
|
66
|
-
assigns = Hash[*definition[:fields].collect { |name| ["#{self.class.name.underscore}_#{name}", self.send(name)] }.flatten(1)]
|
67
|
-
|
68
|
-
|
69
|
-
[definition[:options][:to]].flatten.each do |association|
|
70
|
-
relation = []
|
71
|
-
reflect = self.class.reflect_on_association(association)
|
72
|
-
relation = reflect.relation.macro unless reflect.nil? || reflect.relation.nil?
|
66
|
+
end
|
73
67
|
|
74
|
-
|
68
|
+
def denormalize_to
|
69
|
+
Array(self.denormalize_definitions).find_all do |definition|
|
70
|
+
definition[:options][:to]
|
71
|
+
end.each do |definition|
|
72
|
+
as = definition[:options][:as]
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
74
|
+
assignments = definition[:fields].collect do |source_field|
|
75
|
+
{
|
76
|
+
:source_field => source_field.to_s,
|
77
|
+
:value => self.send(source_field)
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
Array(definition[:options][:to]).each do |association|
|
82
|
+
relation = []
|
83
|
+
reflect = self.class.reflect_on_association(association)
|
84
|
+
relation = reflect.relation.macro unless reflect.nil? || reflect.relation.nil?
|
85
|
+
|
86
|
+
reflect.klass.skip_callback(:save, :before, :denormalize_from) if reflect.klass.try(:is_denormalized?)
|
87
|
+
|
88
|
+
associated = self.send(association)
|
89
|
+
prefix = (as || reflect.inverse_of || reflect.inverse_class_name).to_s.underscore
|
90
|
+
|
91
|
+
if [:embedded_in, :embeds_one, :referenced_in, :references_one, :has_one, :belongs_to].include? relation
|
92
|
+
unless associated.blank?
|
93
|
+
assign_and_save(associated, assignments, prefix)
|
92
94
|
end
|
93
|
-
|
94
|
-
|
95
|
+
else
|
96
|
+
associated.to_a.each { |c| assign_and_save(c, assignments, prefix) }
|
95
97
|
end
|
98
|
+
|
99
|
+
reflect.klass.set_callback(:save, :before, :denormalize_from) if reflect.klass.try(:is_denormalized?)
|
96
100
|
end
|
97
101
|
end
|
98
|
-
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def assign_and_save(obj, assignments, prefix)
|
105
|
+
attributes_hash = Hash[assignments.collect do |assignment|
|
106
|
+
if self.changed_attributes.has_key?(assignment[:source_field])
|
107
|
+
["#{prefix}_#{assignment[:source_field]}", assignment[:value]]
|
108
|
+
end
|
109
|
+
end]
|
110
|
+
|
111
|
+
unless attributes_hash.empty?
|
112
|
+
# The more succinct update_attributes(changes, :without_protection => true) requires Mongoid 3.0.0,
|
113
|
+
# but we only require 2.1.9
|
114
|
+
obj.assign_attributes(attributes_hash, :without_protection => true)
|
115
|
+
obj.save(:validate => false)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
metadata
CHANGED
@@ -1,80 +1,150 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_denormalize
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 3
|
8
|
-
- 0
|
9
|
-
version: 0.3.0
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Logan Raarup
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
date: 2013-06-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: mongoid_denormalize
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bson_ext
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
22
55
|
prerelease: false
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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: jeweler
|
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: guard-rspec
|
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: mongoid
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
31
101
|
version: 2.1.9
|
32
102
|
type: :runtime
|
33
|
-
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.1.9
|
34
110
|
description: Helper module for denormalizing association attributes in Mongoid models.
|
35
111
|
email: logan@logan.dk
|
36
112
|
executables: []
|
37
|
-
|
38
113
|
extensions: []
|
39
|
-
|
40
|
-
extra_rdoc_files:
|
114
|
+
extra_rdoc_files:
|
41
115
|
- LICENSE
|
42
116
|
- README.md
|
43
|
-
files:
|
117
|
+
files:
|
44
118
|
- lib/mongoid_denormalize.rb
|
45
119
|
- lib/railties/denormalize.rake
|
46
120
|
- lib/railties/railtie.rb
|
47
121
|
- LICENSE
|
48
122
|
- README.md
|
49
|
-
has_rdoc: true
|
50
123
|
homepage: http://github.com/logandk/mongoid_denormalize
|
51
124
|
licenses: []
|
52
|
-
|
53
125
|
post_install_message:
|
54
126
|
rdoc_options: []
|
55
|
-
|
56
|
-
require_paths:
|
127
|
+
require_paths:
|
57
128
|
- lib
|
58
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
segments:
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
none: false
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
segments:
|
70
136
|
- 0
|
71
|
-
|
137
|
+
hash: 4386387219584124888
|
138
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
72
144
|
requirements: []
|
73
|
-
|
74
145
|
rubyforge_project:
|
75
|
-
rubygems_version: 1.
|
146
|
+
rubygems_version: 1.8.24
|
76
147
|
signing_key:
|
77
148
|
specification_version: 3
|
78
149
|
summary: Mongoid denormalization helper.
|
79
150
|
test_files: []
|
80
|
-
|