custom_fields 2.12.1 → 2.13.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 +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +4 -5
- data/lib/custom_fields/extensions/active_support.rb +22 -23
- data/lib/custom_fields/extensions/carrierwave.rb +9 -40
- data/lib/custom_fields/extensions/mongoid/association/referenced/has_many.rb +49 -0
- data/lib/custom_fields/extensions/mongoid/association/referenced/has_one.rb +17 -0
- data/lib/custom_fields/extensions/mongoid/association/relatable.rb +30 -0
- data/lib/custom_fields/extensions/mongoid/criteria/queryable/smash.rb +3 -6
- data/lib/custom_fields/extensions/mongoid/document.rb +4 -8
- data/lib/custom_fields/extensions/mongoid/factory.rb +7 -9
- data/lib/custom_fields/extensions/mongoid/fields/i18n.rb +17 -17
- data/lib/custom_fields/extensions/mongoid/fields/localized.rb +21 -21
- data/lib/custom_fields/extensions/mongoid/fields.rb +4 -7
- data/lib/custom_fields/extensions/mongoid/validatable/collection_size.rb +86 -0
- data/lib/custom_fields/extensions/mongoid/{validations → validatable}/macros.rb +3 -2
- data/lib/custom_fields/extensions/origin/smash.rb +4 -5
- data/lib/custom_fields/field.rb +39 -36
- data/lib/custom_fields/source.rb +46 -44
- data/lib/custom_fields/target.rb +11 -12
- data/lib/custom_fields/target_helpers.rb +21 -23
- data/lib/custom_fields/types/belongs_to.rb +6 -20
- data/lib/custom_fields/types/boolean.rb +5 -12
- data/lib/custom_fields/types/color.rb +4 -12
- data/lib/custom_fields/types/date.rb +20 -22
- data/lib/custom_fields/types/date_time.rb +16 -18
- data/lib/custom_fields/types/default.rb +16 -24
- data/lib/custom_fields/types/email.rb +6 -13
- data/lib/custom_fields/types/file.rb +26 -35
- data/lib/custom_fields/types/float.rb +10 -13
- data/lib/custom_fields/types/has_many.rb +12 -16
- data/lib/custom_fields/types/integer.rb +10 -13
- data/lib/custom_fields/types/json.rb +18 -29
- data/lib/custom_fields/types/many_to_many.rb +14 -19
- data/lib/custom_fields/types/money.rb +34 -35
- data/lib/custom_fields/types/password.rb +19 -23
- data/lib/custom_fields/types/relationship_default.rb +4 -16
- data/lib/custom_fields/types/select.rb +43 -51
- data/lib/custom_fields/types/string.rb +5 -13
- data/lib/custom_fields/types/tags.rb +11 -11
- data/lib/custom_fields/types/text.rb +4 -16
- data/lib/custom_fields/version.rb +4 -2
- data/lib/custom_fields.rb +16 -16
- metadata +38 -38
- data/lib/custom_fields/extensions/mongoid/relations/options.rb +0 -19
- data/lib/custom_fields/extensions/mongoid/relations/referenced/in.rb +0 -18
- data/lib/custom_fields/extensions/mongoid/relations/referenced/many.rb +0 -30
- data/lib/custom_fields/extensions/mongoid/validations/collection_size.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c5b67a98147c90e024cfcd50690b26ac3d472837222ab577ed4e8cd211f97cf
|
4
|
+
data.tar.gz: 4564688d1fec136420b4353f23c8ff149f8ea5240c693a54b863925c5a262373
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f4226fa0228d6ca2ab6a4b9d35a621560292edfd8baec8f68387954246d95b101d69ca6fd5ddf5a1a4859f24a2270c65b7917f8d71286388a90e9f54e73efc0
|
7
|
+
data.tar.gz: 772923aa4070480b8e7170783f75e3c7ef33620a6c85bc9b6dbfa31d65a5458373ef476c1ff84678e21ea272a1fe418de6a282b4bc41ecfcc81bf5333f5e2203
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
==============
|
3
3
|
|
4
4
|
[![Travis CI Status][Travis CI Status]][Travis CI]
|
5
|
-
[![Gemnasium Status][Gemnasium Status]][Gemnasium]
|
6
5
|
|
7
6
|
Manage custom fields to a Mongoid document or a collection. This module is one of the core features we implemented in
|
8
7
|
our custom CMS, named LocomotiveCMS. Basically, its aim is to provide to editors a way to manage extra fields to a
|
@@ -16,9 +15,9 @@ The main goals:
|
|
16
15
|
Requirements
|
17
16
|
------------
|
18
17
|
|
19
|
-
* MongoDB
|
20
|
-
* Mongoid
|
21
|
-
* ActiveSupport
|
18
|
+
* MongoDB 6+
|
19
|
+
* Mongoid 8+
|
20
|
+
* ActiveSupport 6+
|
22
21
|
|
23
22
|
Examples
|
24
23
|
--------
|
@@ -93,7 +92,7 @@ Feel free to contact me at did at locomotivecms dot com.
|
|
93
92
|
License
|
94
93
|
-------
|
95
94
|
|
96
|
-
Copyright (c)
|
95
|
+
Copyright (c) 2023 NoCoffee, released under the [MIT License (MIT)], see [MIT-LICENSE].
|
97
96
|
|
98
97
|
[CustomFields]: https://github.com/locomotivecms/custom_fields "Custom fields extension for Mongoid."
|
99
98
|
[Gemnasium]: https://gemnasium.com/locomotivecms/custom_fields "CustomFields at Gemnasium"
|
@@ -1,30 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
module CustomFieldsStringExtension
|
4
|
+
def constantize
|
5
|
+
super
|
6
|
+
rescue NameError => e
|
7
|
+
# DEBUG: puts "constantizing #{self.inspect}"
|
8
|
+
# alright, does it look like a custom_fields dynamic klass ?
|
9
|
+
if self =~ CustomFields::KLASS_REGEXP
|
10
|
+
base = ::Regexp.last_match(1).constantize
|
11
|
+
# we can know it for sure
|
12
|
+
if base.with_custom_fields?
|
13
|
+
relation = base.relations.values.detect do |association|
|
14
|
+
association.options[:custom_fields_parent_klass] == true
|
15
|
+
end
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
17
|
+
# load the class which holds the recipe to build the dynamic klass
|
18
|
+
if relation && parent_instance = relation.klass.find(::Regexp.last_match(2))
|
19
|
+
# DEBUG: puts "re-building #{self}"
|
20
|
+
return parent_instance.klass_with_custom_fields(relation.inverse_of)
|
20
21
|
end
|
21
22
|
end
|
22
|
-
# not a custom_fields dynamic klass or unable to re-build it
|
23
|
-
raise exception
|
24
23
|
end
|
24
|
+
# not a custom_fields dynamic klass or unable to re-build it
|
25
|
+
raise e
|
25
26
|
end
|
26
|
-
|
27
|
-
alias_method :constantize_without_custom_fields, :constantize
|
28
|
-
alias_method :constantize, :constantize_with_custom_fields
|
29
|
-
|
30
27
|
end
|
28
|
+
|
29
|
+
::String.prepend CustomFieldsStringExtension
|
@@ -1,34 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'carrierwave/mongoid'
|
2
4
|
|
3
5
|
module CarrierWave
|
4
|
-
|
5
|
-
module Mongoid
|
6
|
-
|
7
|
-
def mount_uploader_with_localization(column, uploader=nil, options={}, &block)
|
8
|
-
mount_uploader_without_localization(column, uploader, options, &block)
|
9
|
-
|
10
|
-
define_method(:read_uploader) do |name|
|
11
|
-
# puts "read_uploader #{name} / #{read_attribute(name.to_sym).inspect} / #{::Mongoid::Fields::I18n.locale.inspect}" # DEBUG
|
12
|
-
|
13
|
-
value = read_attribute(name.to_sym)
|
14
|
-
|
15
|
-
unless value.nil?
|
16
|
-
self.class.fields[name.to_s].demongoize(value)
|
17
|
-
else
|
18
|
-
nil
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
alias_method :mount_uploader_without_localization, :mount_uploader
|
24
|
-
alias_method :mount_uploader, :mount_uploader_with_localization
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
6
|
class Mounter
|
29
|
-
|
30
7
|
def remove_previous_with_localization(before = nil, after = nil)
|
31
|
-
_before
|
8
|
+
_before = before
|
9
|
+
_after = after
|
32
10
|
locale = ::Mongoid::Fields::I18n.locale.to_s
|
33
11
|
|
34
12
|
# custom case:
|
@@ -37,28 +15,19 @@ module CarrierWave
|
|
37
15
|
# a different name.
|
38
16
|
# We absolutely don't want to erase the file in the default locale
|
39
17
|
if record.class.fields[column.to_s]&.localized? &&
|
40
|
-
|
18
|
+
record.changes[column]&.first == '_new_'
|
41
19
|
_before = [nil]
|
42
20
|
end
|
43
21
|
|
44
22
|
# FIXME: can't reproduce this behavior locally but it happens in production
|
45
|
-
if before && before.first.is_a?(Hash)
|
46
|
-
_before = [before.first[locale]]
|
47
|
-
end
|
23
|
+
_before = [before.first[locale]] if before && before.first.is_a?(Hash)
|
48
24
|
|
49
|
-
if after && after.first.is_a?(Hash)
|
50
|
-
_after = [after.first[locale]]
|
51
|
-
end
|
25
|
+
_after = [after.first[locale]] if after && after.first.is_a?(Hash)
|
52
26
|
|
53
27
|
remove_previous_without_localization(_before, _after)
|
54
28
|
end
|
55
29
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
30
|
+
alias remove_previous_without_localization remove_previous
|
31
|
+
alias remove_previous remove_previous_with_localization
|
60
32
|
end
|
61
|
-
|
62
33
|
end
|
63
|
-
|
64
|
-
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# module Mongoid #:nodoc:
|
4
|
+
# module Relations #:nodoc:
|
5
|
+
# module Referenced #:nodoc:
|
6
|
+
|
7
|
+
# # This class defines the behaviour for all relations that are a
|
8
|
+
# # one-to-many between documents in different collections.
|
9
|
+
# class Many < Relations::Many
|
10
|
+
|
11
|
+
# def build_with_custom_fields(attributes = {}, type = nil)
|
12
|
+
# if base.respond_to?(:custom_fields_for?) && base.custom_fields_for?(relation_metadata.name)
|
13
|
+
# # all the information about how to build the custom class are stored here
|
14
|
+
# recipe = base.custom_fields_recipe_for(relation_metadata.name)
|
15
|
+
# attributes ||= {}
|
16
|
+
# attributes.merge!(custom_fields_recipe: recipe)
|
17
|
+
# # build the class with custom_fields for the first time
|
18
|
+
# type = relation_metadata.klass.klass_with_custom_fields(recipe)
|
19
|
+
# end
|
20
|
+
# build_without_custom_fields(attributes, type)
|
21
|
+
# end
|
22
|
+
|
23
|
+
# alias_method :build_without_custom_fields, :build
|
24
|
+
# alias_method :build, :build_with_custom_fields
|
25
|
+
|
26
|
+
# # new should point to the new build method
|
27
|
+
# alias :new :build_with_custom_fields
|
28
|
+
# end
|
29
|
+
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
|
34
|
+
module CustomFieldsManyExtension
|
35
|
+
def build(attributes = {}, type = nil)
|
36
|
+
if _base.respond_to?(:custom_fields_for?) && _base.custom_fields_for?(association.name)
|
37
|
+
# all the information about how to build the custom class are stored here
|
38
|
+
recipe = _base.custom_fields_recipe_for(association.name)
|
39
|
+
attributes ||= {}
|
40
|
+
attributes.merge!(custom_fields_recipe: recipe)
|
41
|
+
# build the class with custom_fields for the first time
|
42
|
+
type = association.klass.klass_with_custom_fields(recipe)
|
43
|
+
end
|
44
|
+
super(attributes, type)
|
45
|
+
end
|
46
|
+
alias new build
|
47
|
+
end
|
48
|
+
|
49
|
+
::Mongoid::Association::Referenced::HasMany::Proxy.prepend CustomFieldsManyExtension
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CustomFieldsInExtension
|
4
|
+
module ClassMethods
|
5
|
+
def valid_options
|
6
|
+
[:custom_fields_parent_klass] + super
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.prepended(base)
|
11
|
+
class << base
|
12
|
+
prepend ClassMethods
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
::Mongoid::Association::Referenced::HasOne.prepend CustomFieldsInExtension
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CustomFieldsRelatableExtension
|
4
|
+
def resolve_name(mod, name)
|
5
|
+
super
|
6
|
+
rescue NameError => e
|
7
|
+
return name.constantize if name =~ CustomFields::KLASS_REGEXP
|
8
|
+
|
9
|
+
raise e
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate!
|
13
|
+
option = @options.delete(:custom_fields_parent_klass)
|
14
|
+
super.tap do
|
15
|
+
@options[:custom_fields_parent_klass] = option if option
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
[
|
21
|
+
Mongoid::Association::Embedded::EmbeddedIn,
|
22
|
+
Mongoid::Association::Embedded::EmbedsMany,
|
23
|
+
Mongoid::Association::Embedded::EmbedsOne,
|
24
|
+
Mongoid::Association::Referenced::BelongsTo,
|
25
|
+
Mongoid::Association::Referenced::HasMany,
|
26
|
+
Mongoid::Association::Referenced::HasAndBelongsToMany,
|
27
|
+
Mongoid::Association::Referenced::HasOne,
|
28
|
+
].each do |klass|
|
29
|
+
klass.prepend CustomFieldsRelatableExtension
|
30
|
+
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Mongoid
|
3
4
|
class Criteria
|
4
5
|
module Queryable
|
5
|
-
|
6
6
|
# This is a smart hash for use with options and selectors.
|
7
7
|
class Smash < Hash
|
8
|
-
|
9
8
|
private
|
10
9
|
|
11
10
|
# Get the localized value for the key if needed. If the field uses
|
@@ -24,11 +23,9 @@ module Mongoid
|
|
24
23
|
#
|
25
24
|
# @since 1.0.0
|
26
25
|
def localized_key(name, serializer)
|
27
|
-
serializer
|
26
|
+
serializer&.localized? ? "#{name}.#{::Mongoid::Fields::I18n.locale}" : name
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
31
|
-
|
32
29
|
end
|
33
30
|
end
|
34
31
|
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Document #:nodoc:
|
4
|
-
|
5
|
-
module ClassMethods #:nodoc:
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
3
|
+
module Mongoid # :nodoc:
|
4
|
+
module Document # :nodoc:
|
5
|
+
module ClassMethods # :nodoc:
|
7
6
|
# The mongoid default document returns always false.
|
8
7
|
# The documents with custom fields return true.
|
9
8
|
#
|
@@ -12,9 +11,6 @@ module Mongoid #:nodoc:
|
|
12
11
|
def with_custom_fields?
|
13
12
|
false
|
14
13
|
end
|
15
|
-
|
16
14
|
end
|
17
|
-
|
18
15
|
end
|
19
|
-
|
20
16
|
end
|
@@ -1,18 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Mongoid # :nodoc:
|
3
4
|
# Instantiates documents that came from the database.
|
4
5
|
module Factory
|
6
|
+
def from_db_with_custom_fields(klass, attributes = nil, criteria = nil, selected_fields = nil)
|
7
|
+
klass.klass_with_custom_fields(attributes['custom_fields_recipe']) if klass.with_custom_fields?
|
5
8
|
|
6
|
-
|
7
|
-
if klass.with_custom_fields?
|
8
|
-
klass.klass_with_custom_fields(attributes['custom_fields_recipe'])
|
9
|
-
end
|
10
|
-
|
11
|
-
from_db_without_custom_fields(klass, attributes, selected_fields)
|
9
|
+
from_db_without_custom_fields(klass, attributes, criteria, selected_fields)
|
12
10
|
end
|
13
11
|
|
14
12
|
# equivalent for "alias_method_chain :from_db, :custom_fields"
|
15
|
-
|
16
|
-
|
13
|
+
alias from_db_without_custom_fields from_db unless method_defined?(:from_db_without_custom_fields)
|
14
|
+
alias from_db from_db_with_custom_fields
|
17
15
|
end
|
18
16
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :nodoc
|
4
|
+
|
5
|
+
module Mongoid
|
3
6
|
# This module defines behaviour for fields.
|
4
7
|
module Fields
|
5
|
-
|
6
8
|
class I18n
|
7
|
-
|
8
9
|
attr_accessor :locale, :fallbacks
|
9
10
|
|
10
11
|
def self.instance
|
@@ -12,48 +13,47 @@ module Mongoid #:nodoc
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def self.locale
|
15
|
-
|
16
|
+
instance.locale || ::I18n.locale
|
16
17
|
end
|
17
18
|
|
18
19
|
def self.locale=(value)
|
19
|
-
|
20
|
+
instance.locale = begin
|
21
|
+
value.to_sym
|
22
|
+
rescue StandardError
|
23
|
+
nil
|
24
|
+
end
|
20
25
|
end
|
21
26
|
|
22
27
|
def self.fallbacks
|
23
|
-
if !
|
24
|
-
|
28
|
+
if !instance.fallbacks.blank?
|
29
|
+
instance.fallbacks
|
25
30
|
elsif ::I18n.respond_to?(:fallbacks)
|
26
31
|
::I18n.fallbacks
|
27
|
-
else
|
28
|
-
nil
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
32
35
|
def self.fallbacks_for(locale, fallbacks)
|
33
|
-
|
34
|
-
|
36
|
+
instance.fallbacks ||= {}
|
37
|
+
instance.fallbacks[locale.to_sym] = fallbacks
|
35
38
|
end
|
36
39
|
|
37
40
|
def self.fallbacks?
|
38
|
-
!
|
41
|
+
!instance.fallbacks.blank? || (::I18n.respond_to?(:fallbacks) && !::I18n.fallbacks.blank?)
|
39
42
|
end
|
40
43
|
|
41
44
|
def self.clear_fallbacks
|
42
|
-
|
45
|
+
instance.fallbacks.try(:clear)
|
43
46
|
end
|
44
47
|
|
45
48
|
def self.with_locale(new_locale = nil)
|
46
49
|
if new_locale
|
47
|
-
current_locale =
|
50
|
+
current_locale = locale
|
48
51
|
self.locale = new_locale
|
49
52
|
end
|
50
53
|
yield
|
51
54
|
ensure
|
52
55
|
self.locale = current_locale if new_locale
|
53
56
|
end
|
54
|
-
|
55
57
|
end
|
56
|
-
|
57
58
|
end
|
58
|
-
|
59
59
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
module Fields #:nodoc:
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
3
|
+
module Mongoid # :nodoc:
|
4
|
+
module Fields # :nodoc:
|
4
5
|
# The behaviour of the Localized fields in the custom fields gem is different
|
5
6
|
# because we do not rely on I18n directly but on a slight version Mongoid::Fields::I18n.
|
6
7
|
# The main reason is only practical to handle the following case:
|
@@ -9,7 +10,6 @@ module Mongoid #:nodoc:
|
|
9
10
|
# TODO: use this gem instead https://github.com/simi/mongoid-localizer
|
10
11
|
#
|
11
12
|
class Localized < Standard
|
12
|
-
|
13
13
|
def mongoize(object)
|
14
14
|
{ locale.to_s => type.mongoize(object) }
|
15
15
|
end
|
@@ -17,33 +17,33 @@ module Mongoid #:nodoc:
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def lookup(object)
|
20
|
-
if
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
else
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
end
|
20
|
+
value = if object.key?(locale.to_s)
|
21
|
+
object[locale.to_s]
|
22
|
+
elsif object.key?(locale)
|
23
|
+
object[locale]
|
24
|
+
end
|
25
|
+
return value unless value.nil?
|
30
26
|
|
31
|
-
|
32
|
-
fallback_locales = I18n.fallbacks[locale].try(:map, &:to_s)
|
27
|
+
return unless fallbacks? && i18n.respond_to?(:fallbacks)
|
33
28
|
|
34
|
-
|
35
|
-
|
36
|
-
object[_locale]
|
37
|
-
else
|
38
|
-
nil
|
29
|
+
fallback_key = i18n.fallbacks[locale].find do |loc|
|
30
|
+
object.key?(loc.to_s) || object.key?(loc)
|
39
31
|
end
|
32
|
+
object[fallback_key.to_s] || object[fallback_key]
|
33
|
+
end
|
34
|
+
|
35
|
+
def fallbacks?
|
36
|
+
i18n.fallbacks?
|
40
37
|
end
|
41
38
|
|
42
39
|
def locale
|
43
40
|
# be careful, it does not return ::I18n.locale
|
44
|
-
|
41
|
+
i18n.locale
|
45
42
|
end
|
46
43
|
|
44
|
+
def i18n
|
45
|
+
::Mongoid::Fields::I18n
|
46
|
+
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :nodoc
|
4
|
+
|
5
|
+
module Mongoid
|
3
6
|
# This module defines behaviour for fields.
|
4
7
|
module Fields
|
5
|
-
|
6
8
|
module ClassMethods
|
7
|
-
|
8
9
|
# Replace a field with a new type.
|
9
10
|
#
|
10
11
|
# @example Replace the field.
|
@@ -19,13 +20,9 @@ module Mongoid #:nodoc
|
|
19
20
|
# @since 2.1.0
|
20
21
|
def replace_field(name, type, localize = false)
|
21
22
|
# puts "fields[#{name}] = #{fields[name.to_s].inspect} / #{fields.keys.inspect}" # DEBUG
|
22
|
-
#attribute_names.delete_one(name)
|
23
23
|
remove_defaults(name)
|
24
24
|
add_field(name, fields[name.to_s].options.merge(type: type, localize: localize))
|
25
25
|
end
|
26
|
-
|
27
26
|
end
|
28
|
-
|
29
27
|
end
|
30
|
-
|
31
28
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Validatable
|
5
|
+
# Validates that the specified collections do or do not match a certain
|
6
|
+
# size.
|
7
|
+
#
|
8
|
+
# @example Set up the collection size validator.
|
9
|
+
#
|
10
|
+
# class Person
|
11
|
+
# include Mongoid::Document
|
12
|
+
# has_many :addresses
|
13
|
+
#
|
14
|
+
# validates_collection_size_of :addresses, in: 1..10
|
15
|
+
# end
|
16
|
+
class CollectionSizeValidator < Mongoid::Validatable::LengthValidator
|
17
|
+
def validate_each(record, attribute, value)
|
18
|
+
value = collection_to_size(record, attribute)
|
19
|
+
|
20
|
+
super(record, attribute, value)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def collection_to_size(record, attribute)
|
26
|
+
# TODO: find an example with a has_and_belongs_to_many relationship...
|
27
|
+
# relation = record.relations[attribute.to_s]
|
28
|
+
|
29
|
+
# source = case relation.macro
|
30
|
+
# when :embeds_many, :has_many
|
31
|
+
# record.send(attribute)
|
32
|
+
# when :has_and_belongs_to_many
|
33
|
+
# record.send(relation.key.to_sym)
|
34
|
+
# end
|
35
|
+
|
36
|
+
source = record.send(attribute)
|
37
|
+
|
38
|
+
OpenStruct.new(length: source.try(:size) || 0)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# module Mongoid
|
45
|
+
# module Validations
|
46
|
+
|
47
|
+
# # Validates that the specified collections do or do not match a certain
|
48
|
+
# # size.
|
49
|
+
# #
|
50
|
+
# # @example Set up the collection size validator.
|
51
|
+
# #
|
52
|
+
# # class Person
|
53
|
+
# # include Mongoid::Document
|
54
|
+
# # has_many :addresses
|
55
|
+
# #
|
56
|
+
# # validates_collection_size_of :addresses, in: 1..10
|
57
|
+
# # end
|
58
|
+
# class CollectionSizeValidator < Mongoid::Validatable::LengthValidator
|
59
|
+
|
60
|
+
# def validate_each_with_collection(record, attribute, value)
|
61
|
+
# value = collection_to_size(record, attribute)
|
62
|
+
|
63
|
+
# self.validate_each_without_collection(record, attribute, value)
|
64
|
+
# end
|
65
|
+
|
66
|
+
# alias_method :validate_each_without_collection, :validate_each
|
67
|
+
# alias_method :validate_each, :validate_each_with_collection
|
68
|
+
|
69
|
+
# private
|
70
|
+
|
71
|
+
# def collection_to_size(record, attribute)
|
72
|
+
# relation = record.relations[attribute.to_s]
|
73
|
+
|
74
|
+
# source = case relation.macro
|
75
|
+
# when :embeds_many, :has_many
|
76
|
+
# record.send(attribute)
|
77
|
+
# when :has_and_belongs_to_many
|
78
|
+
# record.send(relation.key.to_sym)
|
79
|
+
# end
|
80
|
+
|
81
|
+
# OpenStruct.new(length: source.try(:size) || 0)
|
82
|
+
# end
|
83
|
+
|
84
|
+
# end
|
85
|
+
# end
|
86
|
+
# end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Mongoid
|
2
4
|
module Validatable
|
3
5
|
module Macros
|
@@ -17,9 +19,8 @@ module Mongoid
|
|
17
19
|
#
|
18
20
|
# @since 2.4.0
|
19
21
|
def validates_collection_size_of(*args)
|
20
|
-
validates_with(Mongoid::
|
22
|
+
validates_with(Mongoid::Validatable::CollectionSizeValidator, _merge_attributes(args))
|
21
23
|
end
|
22
|
-
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
+
module Origin
|
3
4
|
# This is a smart hash for use with options and selectors.
|
4
5
|
class Smash < Hash
|
5
|
-
|
6
6
|
private
|
7
7
|
|
8
8
|
# Get the normalized value for the key. If localization is in play the
|
@@ -25,8 +25,7 @@ module Origin
|
|
25
25
|
# @since 1.0.0
|
26
26
|
def normalized_key(name, serializer)
|
27
27
|
# serializer && serializer.localized? ? "#{name}.#{::I18n.locale}" : name
|
28
|
-
serializer
|
28
|
+
serializer&.localized? ? "#{name}.#{::Mongoid::Fields::I18n.locale}" : name
|
29
29
|
end
|
30
|
-
|
31
30
|
end
|
32
|
-
end
|
31
|
+
end
|