mongoid_denormalize 0.0.1 → 0.1.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 +24 -32
- data/lib/mongoid_denormalize.rb +26 -26
- data/spec/models/comment.rb +2 -2
- data/spec/models/post.rb +2 -2
- data/spec/models/user.rb +2 -4
- data/spec/mongoid_denormalize_spec.rb +25 -41
- metadata +3 -3
data/README.md
CHANGED
@@ -25,8 +25,7 @@ In your model:
|
|
25
25
|
include Mongoid::Denormalize
|
26
26
|
|
27
27
|
# Define your denormalized fields
|
28
|
-
denormalize :
|
29
|
-
denormalize :name, :avatar, :from => :user
|
28
|
+
denormalize :name, :email, :from => :user
|
30
29
|
|
31
30
|
|
32
31
|
|
@@ -37,61 +36,54 @@ Example
|
|
37
36
|
include Mongoid::Document
|
38
37
|
include Mongoid::Denormalize
|
39
38
|
|
40
|
-
references_many :
|
39
|
+
references_many :comments
|
41
40
|
|
42
41
|
field :name
|
43
|
-
field :
|
42
|
+
field :email
|
43
|
+
|
44
|
+
denormalize :name, :email, :to => :comments
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
+
def Comment
|
47
48
|
include Mongoid::Document
|
48
49
|
include Mongoid::Denormalize
|
49
50
|
|
50
51
|
referenced_in :user
|
51
52
|
|
52
|
-
field :
|
53
|
-
|
53
|
+
field :body
|
54
|
+
|
55
|
+
denormalize :name, :email, :from => :user
|
54
56
|
end
|
55
57
|
|
56
|
-
>> user = User.create(:name => "John Doe", :
|
57
|
-
>>
|
58
|
-
>>
|
58
|
+
>> user = User.create(:name => "John Doe", :email => "john@doe.com")
|
59
|
+
>> comment = Comment.create(:body => "Lorem ipsum...", :user => user)
|
60
|
+
>> user.comments << comment
|
61
|
+
>> comment.user_name
|
59
62
|
"John Doe"
|
60
|
-
>>
|
61
|
-
"
|
63
|
+
>> comment.user_email
|
64
|
+
"john@doe.com"
|
62
65
|
>> user.update_attributes(:name => "Bill")
|
63
|
-
>>
|
64
|
-
>> post.user_name
|
66
|
+
>> comment.user_name
|
65
67
|
"Bill"
|
66
68
|
|
67
69
|
|
68
70
|
Options
|
69
71
|
-------
|
70
72
|
|
71
|
-
Denormalization can happen
|
72
|
-
|
73
|
+
Denormalization can happen in either or both directions. When using the `:from` option, the associated objects will fetch the values from
|
74
|
+
the parent. When using the `:to` option, the parent will push the values to its children.
|
73
75
|
|
74
|
-
# Basic denormalization. Will set the user_name attribute with the user name.
|
76
|
+
# Basic denormalization. Will set the user_name attribute with the associated user's name.
|
75
77
|
denormalize :name, :from => :user
|
76
78
|
|
77
|
-
#
|
78
|
-
denormalize :
|
79
|
-
|
80
|
-
# Specify denormalized field type. Will set the post_created_at attribute as a Time object.
|
81
|
-
denormalize :created_at, :type => Time, :from => :post
|
79
|
+
# Basic denormalization. Will set the user_name attribute of "self.comments" with "self.name".
|
80
|
+
denormalize :name, :to => :comments
|
82
81
|
|
83
|
-
# Multiple
|
82
|
+
# Multiple fields. Will set the user_name and user_email attributes with the associated user's name and email.
|
84
83
|
denormalize :name, :email, :from => :user
|
85
84
|
|
86
|
-
#
|
87
|
-
|
88
|
-
denormalize(:comment_count, :type => Integer) { |post| post.comments.count }
|
89
|
-
|
90
|
-
# Block denormalization with multiple fields. Will set the post_titles and post_dates attributes with the blocks return value.
|
91
|
-
# The block receives the current instance as the first argument and the name of the denormalized field as the second argument.
|
92
|
-
denormalize :post_titles, :post_dates, :type => Array do |user, field|
|
93
|
-
field == :post_titles ? user.posts.collect(&:title) : user.posts.collect(&:created_at)
|
94
|
-
end
|
85
|
+
# Multiple children. Will set the user_name attribute of "self.posts" and "self.comments" with "self.name".
|
86
|
+
denormalize :name, :to => [:posts, :comments]
|
95
87
|
|
96
88
|
|
97
89
|
Credits
|
data/lib/mongoid_denormalize.rb
CHANGED
@@ -6,10 +6,13 @@ module Mongoid::Denormalize
|
|
6
6
|
|
7
7
|
included do
|
8
8
|
cattr_accessor :denormalize_definitions
|
9
|
+
|
10
|
+
before_save :denormalize_from
|
11
|
+
after_save :denormalize_to
|
9
12
|
end
|
10
13
|
|
11
14
|
module ClassMethods
|
12
|
-
# Set a field or a number of fields to denormalize. Specify the associated object using the :from
|
15
|
+
# Set a field or a number of fields to denormalize. Specify the associated object using the :from or :to options.
|
13
16
|
#
|
14
17
|
# def Post
|
15
18
|
# include Mongoid::Document
|
@@ -19,43 +22,40 @@ module Mongoid::Denormalize
|
|
19
22
|
# references_many :comments
|
20
23
|
#
|
21
24
|
# denormalize :name, :avatar, :from => :user
|
22
|
-
#
|
23
|
-
# denormalize :email, :from => :user, :to => :from_email
|
24
|
-
#
|
25
|
-
# denormalize :comment_count, :type => Integer do |post|
|
26
|
-
# post.comments.count
|
27
|
-
# end
|
25
|
+
# denormalize :created_at, :to => :comments
|
28
26
|
# end
|
29
|
-
def denormalize(*fields
|
27
|
+
def denormalize(*fields)
|
30
28
|
options = fields.pop
|
31
29
|
|
32
|
-
(self.denormalize_definitions ||= []) << { :fields => fields, :options => options
|
30
|
+
(self.denormalize_definitions ||= []) << { :fields => fields, :options => options }
|
33
31
|
|
34
32
|
# Define schema
|
35
|
-
|
36
|
-
|
37
|
-
name
|
38
|
-
else
|
39
|
-
options[:to] ? options[:to] : "#{options[:from]}_#{name}"
|
40
|
-
end
|
41
|
-
|
42
|
-
field denormalized_name, :type => options[:type]
|
33
|
+
unless options[:to]
|
34
|
+
fields.each { |name| field "#{options[:from]}_#{name}", :type => options[:type] }
|
43
35
|
end
|
44
|
-
|
45
|
-
before_validation :denormalize_fields
|
46
36
|
end
|
47
37
|
end
|
48
38
|
|
49
39
|
private
|
50
|
-
def
|
40
|
+
def denormalize_from
|
51
41
|
self.denormalize_definitions.each do |definition|
|
52
|
-
definition[:
|
53
|
-
|
54
|
-
|
55
|
-
|
42
|
+
next if definition[:options][:to]
|
43
|
+
|
44
|
+
definition[:fields].each { |name| self.send("#{definition[:options][:from]}_#{name}=", self.send(definition[:options][:from]).try(name)) }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def denormalize_to
|
49
|
+
self.denormalize_definitions.each do |definition|
|
50
|
+
next unless definition[:options][:to]
|
51
|
+
|
52
|
+
assigns = Hash[*definition[:fields].collect { |name| ["#{self.class.name.underscore}_#{name}", self.send(name)] }.flatten]
|
53
|
+
|
54
|
+
[definition[:options][:to]].flatten.each do |association|
|
55
|
+
if [:embedded_in, :embeds_one, :referenced_in, :references_one].include? self.class.reflect_on_association(association)
|
56
|
+
self.send(association).update_attributes(assigns) unless self.send(association).blank?
|
56
57
|
else
|
57
|
-
|
58
|
-
self.send("#{attribute_name}=", self.send(definition[:options][:from]).try(name))
|
58
|
+
self.send(association).to_a.each { |a| a.update_attributes(assigns) }
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
data/spec/models/comment.rb
CHANGED
@@ -4,10 +4,10 @@ class Comment
|
|
4
4
|
|
5
5
|
field :body
|
6
6
|
|
7
|
-
|
7
|
+
embedded_in :post, :inverse_of => :comments
|
8
8
|
referenced_in :user
|
9
9
|
|
10
10
|
denormalize :name, :from => :user
|
11
|
-
denormalize :email, :from => :user
|
11
|
+
denormalize :email, :from => :user
|
12
12
|
denormalize :created_at, :type => Time, :from => :post
|
13
13
|
end
|
data/spec/models/post.rb
CHANGED
@@ -7,8 +7,8 @@ class Post
|
|
7
7
|
field :created_at, :type => Time
|
8
8
|
|
9
9
|
referenced_in :user
|
10
|
-
|
10
|
+
embeds_many :comments
|
11
11
|
|
12
12
|
denormalize :name, :email, :from => :user
|
13
|
-
denormalize
|
13
|
+
denormalize :created_at, :to => :comments
|
14
14
|
end
|
data/spec/models/user.rb
CHANGED
@@ -5,10 +5,8 @@ class User
|
|
5
5
|
field :name
|
6
6
|
field :email
|
7
7
|
|
8
|
-
|
8
|
+
references_one :post
|
9
9
|
references_many :comments
|
10
10
|
|
11
|
-
denormalize :
|
12
|
-
field == :post_titles ? user.posts.collect(&:title) : user.posts.collect(&:created_at).collect { |t| t + 300 }
|
13
|
-
end
|
11
|
+
denormalize :name, :email, :to => [:post, :comments]
|
14
12
|
end
|
@@ -6,23 +6,21 @@ describe Mongoid::Denormalize do
|
|
6
6
|
c.drop rescue nil
|
7
7
|
end
|
8
8
|
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@comment =
|
9
|
+
@post = Post.create!(:title => "Blog post", :body => "Lorem ipsum...", :created_at => Time.parse("Jan 1 2010 12:00"))
|
10
|
+
@user = User.create!(:name => "John Doe", :email => "john@doe.com", :post => @post)
|
11
|
+
@comment = @post.comments.create(:body => "This is the comment", :user => @user)
|
12
12
|
|
13
|
-
@
|
13
|
+
@user.comments << @comment
|
14
|
+
|
15
|
+
@other_user = User.create!(:name => "Bill")
|
14
16
|
end
|
15
17
|
|
16
|
-
context "denormalize
|
18
|
+
context "denormalize from" do
|
17
19
|
it "should define multiple fields for association" do
|
18
20
|
@post.fields.should have_key "user_name"
|
19
21
|
@post.fields.should have_key "user_email"
|
20
22
|
end
|
21
23
|
|
22
|
-
it "should override the name of the denormalized field" do
|
23
|
-
@comment.fields.should have_key "from_email"
|
24
|
-
end
|
25
|
-
|
26
24
|
it "should default to string field type for associated fields" do
|
27
25
|
@post.fields["user_name"].type.should eql String
|
28
26
|
end
|
@@ -33,12 +31,12 @@ describe Mongoid::Denormalize do
|
|
33
31
|
|
34
32
|
it "should allow multiple declarations for the same association" do
|
35
33
|
@comment.fields.should have_key "user_name"
|
36
|
-
@comment.fields.should have_key "
|
34
|
+
@comment.fields.should have_key "user_email"
|
37
35
|
end
|
38
36
|
|
39
37
|
it "should denormalize fields without specified type" do
|
40
38
|
@comment.user_name.should eql @user.name
|
41
|
-
@comment.
|
39
|
+
@comment.user_email.should eql @user.email
|
42
40
|
@post.user_name.should eql @user.name
|
43
41
|
@post.user_email.should eql @user.email
|
44
42
|
end
|
@@ -47,50 +45,36 @@ describe Mongoid::Denormalize do
|
|
47
45
|
@comment.post_created_at.should eql @post.created_at
|
48
46
|
end
|
49
47
|
|
50
|
-
it "should update denormalized values if changed" do
|
48
|
+
it "should update denormalized values if attribute is changed" do
|
49
|
+
@user.update_attributes(:name => "Bob Doe")
|
50
|
+
|
51
|
+
@comment.user_name.should eql @user.name
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should update denormalized values if object is changed" do
|
51
55
|
@other_user = User.create!(:name => "Bill", :email => "bill@doe.com")
|
52
56
|
|
53
57
|
@comment.user = @other_user
|
54
58
|
@comment.save!
|
55
59
|
|
56
60
|
@comment.user_name.should eql @other_user.name
|
57
|
-
@comment.
|
61
|
+
@comment.user_email.should eql @other_user.email
|
58
62
|
end
|
59
63
|
end
|
60
64
|
|
61
|
-
context "
|
62
|
-
it "should
|
63
|
-
@
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should accept multiple fields for block" do
|
67
|
-
@user.fields.should have_key "post_titles"
|
68
|
-
@user.fields.should have_key "post_dates"
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should allow setting the field type" do
|
72
|
-
@user.fields["post_titles"].type.should eql Array
|
73
|
-
@post.fields["comment_count"].type.should eql Integer
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should denormalize fields using block" do
|
77
|
-
@post.save!
|
78
|
-
@post.comment_count.should eql 1
|
79
|
-
|
65
|
+
context "denormalize to" do
|
66
|
+
it "should push denormalized fields to one-to-one association" do
|
67
|
+
@user.name = "Elvis"
|
80
68
|
@user.save!
|
81
|
-
|
82
|
-
@
|
69
|
+
|
70
|
+
@post.user_name.should eql "Elvis"
|
83
71
|
end
|
84
72
|
|
85
|
-
it "should
|
86
|
-
@post.
|
73
|
+
it "should push denormalized fields to one-to-many association" do
|
74
|
+
@post.created_at = Time.parse("Jan 1 2011 12:00")
|
87
75
|
@post.save!
|
88
76
|
|
89
|
-
@
|
90
|
-
@other_user.save!
|
91
|
-
|
92
|
-
@user.post_titles.should eql []
|
93
|
-
@other_user.post_titles.should eql ["Blog post"]
|
77
|
+
@comment.post_created_at.should eql Time.parse("Jan 1 2011 12:00")
|
94
78
|
end
|
95
79
|
end
|
96
80
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_denormalize
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
- 0
|
9
8
|
- 1
|
10
|
-
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Logan Raarup
|