mongoid-denormalize 0.1.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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