mongoid-denormalize 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cecaa0d338d86451e2d2808712767f0e6862aed4
4
- data.tar.gz: 53e285e91e43bd2cedce3430fcf49fed0f953a63
2
+ SHA256:
3
+ metadata.gz: 7c7d7ab9d80881adaa4e262eee1326301f9e90d6e279447aef67beec3d65a0be
4
+ data.tar.gz: ad68e00030e827e28541cff160411f406dad2c69ea53ca54baf53758a16aa506
5
5
  SHA512:
6
- metadata.gz: 4de17b1f7116ea41d2593dafa284e11a3c41058a8b35ea8a3dcbee2cf73f23a3732028f50764dd2703ac485165842de14634eab8cb14fb89a485dd538a680e5f
7
- data.tar.gz: 6e944fc4822da56b58d2e7a582750e2a980d67dad51a194cc1898eb644fe336792ae49b9385b2d60b7d2ff96d6a513d27123fa879875e75c730802e6a6771a59
6
+ metadata.gz: 0f765af8e61525c9609afb0da02a3c90f9a2070f4056d35731f6977a81ff0f7305ace737a1f3a16dc792da8b58e6ba0f6ffc9e93d43d0c6306fd6347cfe44eba
7
+ data.tar.gz: 37a5efcf39b2618653331ae1b416a17730ec854372f708da1b4e742b51dd7ffe72f8190c2aea7f4a6f95fe9fbb5f932ffdf9c5fd8edffff591292089260bad6c
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ *.gem
10
11
 
11
12
  # rspec failure tracking
12
13
  .rspec_status
data/.travis.yml CHANGED
@@ -1,15 +1,13 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.4
5
- before_install: gem install bundler -v 1.15.4
4
+ - 2.7
5
+ before_install: gem install bundler -v 2.2
6
+
7
+ gemfile:
8
+ - Gemfile
9
+ - gemfiles/mongoid-6.0.gemfile
10
+ - gemfiles/mongoid-7.0.gemfile
6
11
 
7
12
  services:
8
13
  - mongodb
9
-
10
- addons:
11
- apt:
12
- sources:
13
- - mongodb-3.4-precise
14
- packages:
15
- - mongodb-org-server
data/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Mongoid::Denormalize
2
- ![Build Status](https://travis-ci.org/rjurado01/mongoid-denormalize.svg?branch=master)
2
+ ![Build Status](https://travis-ci.org/nosolosoftware/mongoid-denormalize.svg?branch=master)
3
3
 
4
- Helper module for denormalizing association attributes in Mongoid models
4
+ Helper module for denormalizing association attributes in Mongoid models.
5
+
6
+ This gem is tested on mongoid 6.x and 7.x.
5
7
 
6
8
  ## Installation
7
9
 
@@ -31,7 +33,7 @@ include Mongoid::Denormalize
31
33
  denormalize :name, :email, from: :user
32
34
  ```
33
35
 
34
- You need to add `inverse_of` to `belongs_to` side if `has_many` target name is diferent from model:
36
+ You need to add `inverse_of` to `belongs_to` side if relation name is diferent from model:
35
37
 
36
38
  ```ruby
37
39
  class Club
@@ -52,7 +54,6 @@ end
52
54
  ```ruby
53
55
  class User
54
56
  include Mongoid::Document
55
- include Mongoid::Denormalize
56
57
 
57
58
  field :name
58
59
 
@@ -85,6 +86,45 @@ end
85
86
  "User2"
86
87
  ```
87
88
 
89
+ ## Options of denormalize
90
+
91
+ ### as
92
+
93
+ Enables to customize the final field name
94
+
95
+ ```ruby
96
+ denormalize :name, from: :top, as: :custom_name
97
+ ```
98
+
99
+ It will create the field `custom_name` with the content of `top.name`. Also support an array:
100
+
101
+ ```ruby
102
+ denormalize :name, :age, from: :top, as: [:custom_name, :custom_age]
103
+ ```
104
+
105
+ ### prefix
106
+
107
+ In somes cases it could be interesting to customize the prefix of the final name, instead of using the basic `from_field`
108
+
109
+ ```ruby
110
+ denormalize :color, :name, from: :top, prefix: :ancestor
111
+ ```
112
+
113
+ It will create the fields `ancestor_name` and `ancestor_color` with the content of `top.name` and `top.color`.
114
+
115
+ ### child_callback
116
+
117
+ By default when a child is created the denormalization is executed into `before_save` hook.
118
+ This option let you change this callback by other, for example:
119
+
120
+ ```ruby
121
+ denormalize :name, from: :top, child_callback: :before_validation
122
+
123
+ validate :top_name, presence: true
124
+ ```
125
+
126
+ It will denormalize field `name` into `before_validation` callback so that we can validate it.
127
+
88
128
  ## Development
89
129
 
90
130
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -93,7 +133,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
93
133
 
94
134
  ## Contributing
95
135
 
96
- Bug reports and pull requests are welcome on GitHub at https://github.com/rjurado01/mongoid-denormalize.
136
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nosolosoftware/mongoid-denormalize.
97
137
 
98
138
  ## License
99
139
 
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-normalize-strings.gemspec
4
+ gemspec path: '../'
5
+
6
+ gem 'rake'
7
+ gem 'mongoid', "~> 5.0"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-normalize-strings.gemspec
4
+ gemspec path: '../'
5
+
6
+ gem 'rake'
7
+ gem 'mongoid', "~> 6.0"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-normalize-strings.gemspec
4
+ gemspec path: '../'
5
+
6
+ gem 'rake'
7
+ gem 'mongoid', "~> 7.0"
@@ -1,4 +1,4 @@
1
- require "mongoid-denormalize/version"
1
+ require 'mongoid-denormalize/version'
2
2
 
3
3
  module Mongoid
4
4
  module Denormalize
@@ -8,40 +8,106 @@ module Mongoid
8
8
 
9
9
  module ClassMethods
10
10
  def denormalize(*args)
11
- options = args.pop
11
+ *fields, options = args
12
12
 
13
- unless options.is_a?(Hash) && (from = options[:from]&.to_s)
14
- raise ArgumentError, 'Option :from is needed (e.g. delegate :name, from: :user).'
13
+ unless options.is_a?(Hash) && options[:from]
14
+ raise ArgumentError, 'Option :from is needed (e.g. denormalize :name, from: :user).'
15
15
  end
16
16
 
17
+ fields = Mongoid::Denormalize.get_fields_with_names(self, fields, options)
18
+
17
19
  # Add fields to model
18
- args.each { |field| field "#{from}_#{field}" }
19
-
20
- # Denormalize fields when model is saved and 'from' has changed
21
- before_save do
22
- if send(from) && send("#{from}_id_changed?")
23
- args.each do |field|
24
- send("#{from}_#{field}=", send(from).send(field))
25
- end
26
- end
20
+ fields.each { |field| field field[:as], type: field[:type] }
21
+
22
+ # Add hooks
23
+ Mongoid::Denormalize.add_hook_to_child(self, fields, options)
24
+ Mongoid::Denormalize.add_hook_to_parent(self, fields, options)
25
+ end
26
+ end
27
+
28
+ # Check options and return name for each field
29
+ def self.get_fields_with_names(child_class, fields, options)
30
+ parent = parent_class(child_class, options[:from].to_s)
31
+
32
+ if options.include?(:as)
33
+ options[:as] = [options[:as]] unless options[:as].is_a?(Array)
34
+
35
+ unless fields.size == options[:as].size
36
+ raise ArgumentError, 'When option :as is used you must pass a name for each field.'
27
37
  end
28
38
 
29
- from_class = (relations[from].class_name || relations[from].name.capitalize).constantize
30
- model_class = model_name.name
31
- inverse_of = relations[from].inverse_of || model_name.route_key.pluralize
39
+ return fields.map.with_index do |field, index|
40
+ {name: field, as: options[:as][index], type: field_type(parent, field)}
41
+ end
42
+ elsif options.include?(:prefix)
43
+ return fields.map do |field|
44
+ {name: field, as: "#{options[:prefix]}_#{field}", type: field_type(parent, field)}
45
+ end
46
+ end
32
47
 
33
- # When 'from' is updated, update all childs
34
- from_class.send(:after_update) do
35
- attributes = {}
36
- args.each { |field| attributes["#{from}_#{field}"] = send(field) }
48
+ fields.map do |field|
49
+ {name: field, as: "#{options[:from]}_#{field}", type: field_type(parent, field)}
50
+ end
51
+ end
52
+
53
+ # Add hook to child class to denormalize fields when parent relation is changed
54
+ def self.add_hook_to_child(child_class, fields, options)
55
+ from = options[:from].to_s
37
56
 
38
- unless relations[inverse_of.to_s]
39
- raise "Option :inverse_of is needed for 'belongs_to :#{from}' into #{model_class}."
57
+ child_class.send(options[:child_callback] || 'before_save') do
58
+ if send("#{from}_id_changed?")
59
+ fields.each do |field|
60
+ send("#{field[:as]}=", send(from)&.send(field[:name]))
40
61
  end
62
+ end
63
+ end
64
+ end
65
+
66
+ # Add hook to parent class to denormalize fields when parent object is updated
67
+ def self.add_hook_to_parent(child_class, fields, options)
68
+ from = options[:from].to_s
69
+
70
+ parent = parent_class(child_class, from)
71
+
72
+ relation = parent.relations[child_class.relations[from].inverse_of.to_s] ||
73
+ parent.relations[child_class.model_name.plural] ||
74
+ parent.relations[child_class.model_name.singular]
75
+
76
+ unless relation
77
+ raise "Option :inverse_of is needed for 'belongs_to :#{from}' into #{child_class}."
78
+ end
41
79
 
42
- send(inverse_of).update_all('$set' => attributes)
80
+ parent.after_update do
81
+ attributes = {}
82
+ fields.each do |field|
83
+ attributes[field[:as]] = send(field[:name]) if send("#{field[:name]}_changed?")
84
+ end
85
+ next if attributes.blank?
86
+
87
+ case relation.relation.to_s
88
+ when 'Mongoid::Relations::Referenced::One',
89
+ 'Mongoid::Association::Referenced::HasOne::Proxy'
90
+ if (document = send(relation.name))
91
+ document.collection.update_one({_id: document._id}, {'$set' => attributes})
92
+ end
93
+ when 'Mongoid::Relations::Referenced::Many',
94
+ 'Mongoid::Association::Referenced::HasMany::Proxy'
95
+ send(relation.name).update_all('$set' => attributes)
96
+ else
97
+ raise "Relation type unsupported: #{relation.relation}"
43
98
  end
44
99
  end
45
100
  end
101
+
102
+ # Retrieve parent class
103
+ def self.parent_class(child_class, from)
104
+ (child_class.relations[from].class_name || child_class.relations[from].name.capitalize)
105
+ .constantize
106
+ end
107
+
108
+ # Retreive the type of a field from the given class
109
+ def self.field_type(klass, field)
110
+ klass.fields[field.to_s].options[:type]
111
+ end
46
112
  end
47
113
  end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module Denormalize
3
- VERSION = "0.1.0"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -22,8 +22,9 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_development_dependency 'bundler', '~> 1.15'
26
- spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'bundler', '~> 2.2'
26
+ spec.add_development_dependency 'mongoid-compatibility', '~> 0.5.1'
27
+ spec.add_development_dependency 'rake', '~> 13.0'
27
28
  spec.add_development_dependency 'rspec', '~> 3.0'
28
- spec.add_dependency 'mongoid'
29
+ spec.add_dependency 'mongoid', ['>= 6.0', '< 8.0']
29
30
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid-denormalize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - rjurado01
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-15 00:00:00.000000000 Z
11
+ date: 2021-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.15'
19
+ version: '2.2'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.15'
26
+ version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mongoid-compatibility
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.5.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.5.1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '10.0'
47
+ version: '13.0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '10.0'
54
+ version: '13.0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +72,20 @@ dependencies:
58
72
  requirements:
59
73
  - - ">="
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
75
+ version: '6.0'
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: '8.0'
62
79
  type: :runtime
63
80
  prerelease: false
64
81
  version_requirements: !ruby/object:Gem::Requirement
65
82
  requirements:
66
83
  - - ">="
67
84
  - !ruby/object:Gem::Version
68
- version: '0'
85
+ version: '6.0'
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '8.0'
69
89
  description: Helper module for denormalizing relations attributes in Mongoid models
70
90
  email:
71
91
  - rjurado01@gmail.com
@@ -82,6 +102,9 @@ files:
82
102
  - Rakefile
83
103
  - bin/console
84
104
  - bin/setup
105
+ - gemfiles/mongoid-5.0.gemfile
106
+ - gemfiles/mongoid-6.0.gemfile
107
+ - gemfiles/mongoid-7.0.gemfile
85
108
  - lib/mongoid-denormalize.rb
86
109
  - lib/mongoid-denormalize/version.rb
87
110
  - mongoid-denormalize.gemspec
@@ -104,8 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
127
  - !ruby/object:Gem::Version
105
128
  version: '0'
106
129
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.5.2
130
+ rubygems_version: 3.1.4
109
131
  signing_key:
110
132
  specification_version: 4
111
133
  summary: Denormalize fields from relations