gnuside-custom_fields 2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.textile +70 -0
- data/config/locales/de.yml +15 -0
- data/config/locales/en.yml +21 -0
- data/config/locales/fr.yml +25 -0
- data/config/locales/pt-BR.yml +9 -0
- data/config/locales/ru.yml +15 -0
- data/lib/custom_fields/extensions/active_support.rb +28 -0
- data/lib/custom_fields/extensions/carrierwave.rb +25 -0
- data/lib/custom_fields/extensions/mongoid/document.rb +21 -0
- data/lib/custom_fields/extensions/mongoid/factory.rb +20 -0
- data/lib/custom_fields/extensions/mongoid/fields/i18n.rb +55 -0
- data/lib/custom_fields/extensions/mongoid/fields/localized.rb +39 -0
- data/lib/custom_fields/extensions/mongoid/fields.rb +31 -0
- data/lib/custom_fields/extensions/mongoid/relations/referenced/in.rb +22 -0
- data/lib/custom_fields/extensions/mongoid/relations/referenced/many.rb +34 -0
- data/lib/custom_fields/extensions/mongoid/validations/collection_size.rb +43 -0
- data/lib/custom_fields/extensions/mongoid/validations/macros.rb +25 -0
- data/lib/custom_fields/extensions/origin/smash.rb +33 -0
- data/lib/custom_fields/field.rb +106 -0
- data/lib/custom_fields/source.rb +347 -0
- data/lib/custom_fields/target.rb +99 -0
- data/lib/custom_fields/target_helpers.rb +192 -0
- data/lib/custom_fields/types/belongs_to.rb +65 -0
- data/lib/custom_fields/types/boolean.rb +55 -0
- data/lib/custom_fields/types/date.rb +97 -0
- data/lib/custom_fields/types/date_time.rb +97 -0
- data/lib/custom_fields/types/default.rb +103 -0
- data/lib/custom_fields/types/email.rb +60 -0
- data/lib/custom_fields/types/file.rb +74 -0
- data/lib/custom_fields/types/float.rb +52 -0
- data/lib/custom_fields/types/has_many.rb +74 -0
- data/lib/custom_fields/types/integer.rb +54 -0
- data/lib/custom_fields/types/many_to_many.rb +75 -0
- data/lib/custom_fields/types/money.rb +146 -0
- data/lib/custom_fields/types/relationship_default.rb +44 -0
- data/lib/custom_fields/types/select.rb +217 -0
- data/lib/custom_fields/types/string.rb +55 -0
- data/lib/custom_fields/types/tags.rb +35 -0
- data/lib/custom_fields/types/text.rb +65 -0
- data/lib/custom_fields/version.rb +6 -0
- data/lib/custom_fields.rb +74 -0
- metadata +244 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Boolean
|
6
|
+
|
7
|
+
module Field; end
|
8
|
+
|
9
|
+
module Target
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Adds a boolean field. It can not be required.
|
16
|
+
#
|
17
|
+
# @param [ Class ] klass The class to modify
|
18
|
+
# @param [ Hash ] rule It contains the name of the field.
|
19
|
+
#
|
20
|
+
def apply_boolean_custom_field(klass, rule)
|
21
|
+
klass.field rule['name'], type: ::Boolean, localize: rule['localized'] || false, default: false
|
22
|
+
end
|
23
|
+
|
24
|
+
# Build a hash storing the boolean value (true / false) for
|
25
|
+
# a boolean custom field of an instance.
|
26
|
+
#
|
27
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
28
|
+
# @param [ String ] name The name of the boolean custom field
|
29
|
+
#
|
30
|
+
# @return [ Hash ] field name => true / false
|
31
|
+
#
|
32
|
+
def boolean_attribute_get(instance, name)
|
33
|
+
default_attribute_get(instance, name)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the value for the instance and the boolean field specified by
|
37
|
+
# the 2 params.
|
38
|
+
#
|
39
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
40
|
+
# @param [ String ] name The name of the boolean custom field
|
41
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
42
|
+
#
|
43
|
+
def boolean_attribute_set(instance, name, attributes)
|
44
|
+
self.default_attribute_set(instance, name, attributes)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Date
|
6
|
+
|
7
|
+
module Field; end
|
8
|
+
|
9
|
+
module Target
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Adds a date field
|
16
|
+
#
|
17
|
+
# @param [ Class ] klass The class to modify
|
18
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
19
|
+
#
|
20
|
+
def apply_date_custom_field(klass, rule)
|
21
|
+
name = rule['name']
|
22
|
+
|
23
|
+
klass.field name, type: ::Date, localize: rule['localized'] || false
|
24
|
+
|
25
|
+
# other methods
|
26
|
+
klass.send(:define_method, :"formatted_#{name}") { _get_formatted_date(name) }
|
27
|
+
klass.send(:define_method, :"formatted_#{name}=") { |value| _set_formatted_date(name, value) }
|
28
|
+
|
29
|
+
if rule['required']
|
30
|
+
klass.validates_presence_of name, :"formatted_#{name}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Build a hash storing the formatted value for
|
35
|
+
# a date custom field of an instance.
|
36
|
+
#
|
37
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
38
|
+
# @param [ String ] name The name of the date custom field
|
39
|
+
#
|
40
|
+
# @return [ Hash ] field name => formatted date
|
41
|
+
#
|
42
|
+
def date_attribute_get(instance, name)
|
43
|
+
if value = instance.send(:"formatted_#{name}")
|
44
|
+
{ name => value, "formatted_#{name}" => value }
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set the value for the instance and the date field specified by
|
51
|
+
# the 2 params.
|
52
|
+
#
|
53
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
54
|
+
# @param [ String ] name The name of the date custom field
|
55
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
56
|
+
#
|
57
|
+
def date_attribute_set(instance, name, attributes)
|
58
|
+
return unless attributes.key?(name) || attributes.key?("formatted_#{name}")
|
59
|
+
|
60
|
+
value = attributes[name] || attributes["formatted_#{name}"]
|
61
|
+
|
62
|
+
instance.send(:"formatted_#{name}=", value)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def _set_formatted_date(name, value)
|
70
|
+
if value.is_a?(::String) && !value.blank?
|
71
|
+
date = ::Date._strptime(value, self._formatted_date_format)
|
72
|
+
|
73
|
+
if date
|
74
|
+
value = ::Date.new(date[:year], date[:mon], date[:mday])
|
75
|
+
else
|
76
|
+
value = ::Date.parse(value) rescue nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
self.send(:"#{name}=", value)
|
81
|
+
end
|
82
|
+
|
83
|
+
def _get_formatted_date(name)
|
84
|
+
self.send(name.to_sym).strftime(self._formatted_date_format) rescue nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def _formatted_date_format
|
88
|
+
I18n.t('date.formats.default')
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module DateTime
|
6
|
+
|
7
|
+
module Field; end
|
8
|
+
|
9
|
+
module Target
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Adds a date_time field
|
16
|
+
#
|
17
|
+
# @param [ Class ] klass The class to modify
|
18
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
19
|
+
#
|
20
|
+
def apply_date_time_custom_field(klass, rule)
|
21
|
+
name = rule['name']
|
22
|
+
|
23
|
+
klass.field name, type: ::DateTime, localize: rule['localized'] || false
|
24
|
+
|
25
|
+
# other methods
|
26
|
+
klass.send(:define_method, :"formatted_#{name}") { _get_formatted_date_time(name) }
|
27
|
+
klass.send(:define_method, :"formatted_#{name}=") { |value| _set_formatted_date_time(name, value) }
|
28
|
+
|
29
|
+
if rule['required']
|
30
|
+
klass.validates_presence_of name, :"formatted_#{name}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Build a hash storing the formatted value for
|
35
|
+
# a date_time custom field of an instance.
|
36
|
+
#
|
37
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
38
|
+
# @param [ String ] name The name of the date_time custom field
|
39
|
+
#
|
40
|
+
# @return [ Hash ] field name => formatted date_time
|
41
|
+
#
|
42
|
+
def date_time_attribute_get(instance, name)
|
43
|
+
if value = instance.send(:"formatted_#{name}")
|
44
|
+
{ name => value, "formatted_#{name}" => value }
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set the value for the instance and the date_time field specified by
|
51
|
+
# the 2 params.
|
52
|
+
#
|
53
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
54
|
+
# @param [ String ] name The name of the date_time custom field
|
55
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
56
|
+
#
|
57
|
+
def date_time_attribute_set(instance, name, attributes)
|
58
|
+
return unless attributes.key?(name) || attributes.key?("formatted_#{name}")
|
59
|
+
|
60
|
+
value = attributes[name] || attributes["formatted_#{name}"]
|
61
|
+
|
62
|
+
instance.send(:"formatted_#{name}=", value)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def _set_formatted_date_time(name, value)
|
70
|
+
if value.is_a?(::String) && !value.blank?
|
71
|
+
date_time = ::DateTime._strptime(value, self._formatted_date_time_format)
|
72
|
+
|
73
|
+
if date_time
|
74
|
+
value = ::Time.zone.local(date_time[:year], date_time[:mon], date_time[:mday], date_time[:hour], date_time[:min], date_time[:sec] || 0)#, date_time[:zone] || "")
|
75
|
+
else
|
76
|
+
value = ::Time.zone.parse(value) rescue nil
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
self.send(:"#{name}=", value)
|
81
|
+
end
|
82
|
+
|
83
|
+
def _get_formatted_date_time(name)
|
84
|
+
self.send(name.to_sym).strftime(self._formatted_date_time_format) rescue nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def _formatted_date_time_format
|
88
|
+
I18n.t('time.formats.default')
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Default
|
6
|
+
|
7
|
+
module Field
|
8
|
+
|
9
|
+
# Build the mongodb updates based on
|
10
|
+
# the new state of the field
|
11
|
+
#
|
12
|
+
# @param [ Hash ] memo Store the updates
|
13
|
+
#
|
14
|
+
# @return [ Hash ] The memo object upgraded
|
15
|
+
#
|
16
|
+
def collect_default_diff(memo)
|
17
|
+
# puts "collect_default_diff #{self.name}: #{self.persisted?} / #{self.destroyed?}" # DEBUG
|
18
|
+
if self.persisted?
|
19
|
+
if self.destroyed?
|
20
|
+
memo['$unset'][self.name] = 1
|
21
|
+
elsif self.changed?
|
22
|
+
if self.changes.key?('name')
|
23
|
+
old_name, new_name = self.changes['name']
|
24
|
+
memo['$rename'][old_name] = new_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
(memo['$set']['custom_fields_recipe.rules'] ||= []) << self.to_recipe
|
30
|
+
|
31
|
+
memo
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
module Target
|
37
|
+
|
38
|
+
extend ActiveSupport::Concern
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
|
42
|
+
# Modify the target class according to the rule.
|
43
|
+
# By default, it declares the field and a validator
|
44
|
+
# if specified by the rule
|
45
|
+
#
|
46
|
+
# @param [ Class ] klass The class to modify
|
47
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
48
|
+
#
|
49
|
+
def apply_custom_field(klass, rule)
|
50
|
+
klass.field rule['name'], localize: rule['localized'] || false
|
51
|
+
|
52
|
+
klass.validates_presence_of rule['name'] if rule['required']
|
53
|
+
klass.validates_uniqueness_of rule['name'], scope: :_type if rule['unique']
|
54
|
+
end
|
55
|
+
|
56
|
+
# Build a hash storing the formatted (or not) values
|
57
|
+
# for a custom field of an instance.
|
58
|
+
# Since aliases are accepted, we return a hash. Beside,
|
59
|
+
# it is more convenient to use (ex: API).
|
60
|
+
# By default, it only returns hash with only one entry
|
61
|
+
# whose key is the second parameter and the value the
|
62
|
+
# value of the field in the instance given in first parameter.
|
63
|
+
#
|
64
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
65
|
+
# @param [ String ] name The name of the custom field
|
66
|
+
#
|
67
|
+
# @return [ Hash ] field name => formatted value or empty hash if no value
|
68
|
+
#
|
69
|
+
def default_attribute_get(instance, name)
|
70
|
+
unless (value = instance.send(name.to_sym)).nil?
|
71
|
+
{ name => instance.send(name.to_sym) }
|
72
|
+
else
|
73
|
+
{}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Set the value for the instance and the field specified by
|
78
|
+
# the 2 params.
|
79
|
+
# Since the value can come from different attributes and other
|
80
|
+
# params can modify the instance too, we need to pass a hash
|
81
|
+
# instead of a single value.
|
82
|
+
#
|
83
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
84
|
+
# @param [ String ] name The name of the custom field
|
85
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
86
|
+
#
|
87
|
+
def default_attribute_set(instance, name, attributes)
|
88
|
+
# do not go further if the name is not one of the attributes keys.
|
89
|
+
return unless attributes.key?(name)
|
90
|
+
|
91
|
+
# simple assign
|
92
|
+
instance.send(:"#{name}=", attributes[name])
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Email
|
6
|
+
|
7
|
+
module Field; end
|
8
|
+
|
9
|
+
module Target
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Add a string field
|
16
|
+
#
|
17
|
+
# @param [ Class ] klass The class to modify
|
18
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
19
|
+
#
|
20
|
+
def apply_email_custom_field(klass, rule)
|
21
|
+
name = rule['name']
|
22
|
+
|
23
|
+
klass.field name, type: ::String, localize: rule['localized'] || false
|
24
|
+
klass.validates_presence_of name if rule['required']
|
25
|
+
klass.validates_format_of name, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/, allow_blank: !rule['required']
|
26
|
+
klass.validates_uniqueness_of rule['name'], scope: :_type if rule['unique']
|
27
|
+
end
|
28
|
+
|
29
|
+
# Build a hash storing the raw value for
|
30
|
+
# a string custom field of an instance.
|
31
|
+
#
|
32
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
33
|
+
# @param [ String ] name The name of the string custom field
|
34
|
+
#
|
35
|
+
# @return [ Hash ] field name => raw value
|
36
|
+
#
|
37
|
+
def email_attribute_get(instance, name)
|
38
|
+
self.default_attribute_get(instance, name)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set the value for the instance and the string field specified by
|
42
|
+
# the 2 params.
|
43
|
+
#
|
44
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
45
|
+
# @param [ String ] name The name of the string custom field
|
46
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
47
|
+
#
|
48
|
+
def email_attribute_set(instance, name, attributes)
|
49
|
+
self.default_attribute_set(instance, name, attributes)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module File
|
6
|
+
|
7
|
+
module Field; end
|
8
|
+
|
9
|
+
module Target
|
10
|
+
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Adds a file field (using carrierwave)
|
16
|
+
#
|
17
|
+
# @param [ Class ] klass The class to modify
|
18
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
19
|
+
#
|
20
|
+
def apply_file_custom_field(klass, rule)
|
21
|
+
name = rule['name']
|
22
|
+
|
23
|
+
klass.mount_uploader name, FileUploader
|
24
|
+
|
25
|
+
if rule['localized'] == true
|
26
|
+
klass.replace_field name, ::String, true
|
27
|
+
end
|
28
|
+
|
29
|
+
if rule['required']
|
30
|
+
klass.validates_presence_of name
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Build a hash storing the url for a file custom field of an instance.
|
35
|
+
#
|
36
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
37
|
+
# @param [ String ] name The name of the file custom field
|
38
|
+
#
|
39
|
+
# @return [ Hash ] field name => url or empty hash if no file
|
40
|
+
#
|
41
|
+
def file_attribute_get(instance, name)
|
42
|
+
if instance.send(:"#{name}?") #"
|
43
|
+
value = instance.send(name.to_sym).url
|
44
|
+
{ name => value, "#{name}_url" => value }
|
45
|
+
else
|
46
|
+
{}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Set the value for the instance and the file field specified by
|
51
|
+
# the 2 params.
|
52
|
+
#
|
53
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
54
|
+
# @param [ String ] name The name of the file custom field
|
55
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
56
|
+
#
|
57
|
+
def file_attribute_set(instance, name, attributes)
|
58
|
+
[name, "remote_#{name}_url", "remove_#{name}"].each do |_name|
|
59
|
+
self.default_attribute_set(instance, _name, attributes)
|
60
|
+
end.compact
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class FileUploader < ::CarrierWave::Uploader::Base
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Float
|
4
|
+
|
5
|
+
module Field; end
|
6
|
+
|
7
|
+
module Target
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
# Add a string field
|
13
|
+
#
|
14
|
+
# @param [ Class ] klass The class to modify
|
15
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
16
|
+
#
|
17
|
+
def apply_float_custom_field(klass, rule)
|
18
|
+
klass.field rule['name'], type: ::Float, localize: rule['localized'] || false
|
19
|
+
klass.validates_presence_of rule['name'] if rule['required']
|
20
|
+
klass.validates rule['name'], numericality: true, if: ->(x){ rule['required'] }
|
21
|
+
end
|
22
|
+
|
23
|
+
# Build a hash storing the raw value for
|
24
|
+
# a string custom field of an instance.
|
25
|
+
#
|
26
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
27
|
+
# @param [ String ] name The name of the string custom field
|
28
|
+
#
|
29
|
+
# @return [ Hash ] field name => raw value
|
30
|
+
#
|
31
|
+
def float_attribute_get(instance, name)
|
32
|
+
self.default_attribute_get(instance, name)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set the value for the instance and the string field specified by
|
36
|
+
# the 2 params.
|
37
|
+
#
|
38
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
39
|
+
# @param [ String ] name The name of the string custom field
|
40
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
41
|
+
#
|
42
|
+
def float_attribute_set(instance, name, attributes)
|
43
|
+
self.default_attribute_set(instance, name, attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
end # ClassMethods
|
47
|
+
|
48
|
+
end # Target
|
49
|
+
|
50
|
+
end # Float
|
51
|
+
end # Types
|
52
|
+
end # CustomFields
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module HasMany
|
6
|
+
|
7
|
+
module Field
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
def has_many_to_recipe
|
14
|
+
{ 'class_name' => self.class_name, 'inverse_of' => self.inverse_of, 'order_by' => self.order_by }
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_many_is_relationship?
|
18
|
+
self.type == 'has_many'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
module Target
|
26
|
+
|
27
|
+
extend ActiveSupport::Concern
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
|
31
|
+
# Adds a has_many relationship between 2 mongoid models
|
32
|
+
#
|
33
|
+
# @param [ Class ] klass The class to modify
|
34
|
+
# @param [ Hash ] rule It contains the name of the relation and if it is required or not
|
35
|
+
#
|
36
|
+
def apply_has_many_custom_field(klass, rule)
|
37
|
+
# puts "#{klass.inspect}.has_many #{rule['name'].inspect}, class_name: #{rule['class_name'].inspect}, inverse_of: #{rule['inverse_of']}" # DEBUG
|
38
|
+
position_name = "position_in_#{rule['inverse_of']}"
|
39
|
+
|
40
|
+
_order_by = rule['order_by'] || position_name.to_sym.asc
|
41
|
+
_inverse_of = rule['inverse_of'].blank? ? nil : rule['inverse_of'] # an empty String can cause weird behaviours
|
42
|
+
|
43
|
+
klass.has_many rule['name'], class_name: rule['class_name'], inverse_of: _inverse_of, order: _order_by do
|
44
|
+
|
45
|
+
def filtered(conditions = {}, order_by = nil)
|
46
|
+
list = conditions.empty? ? self.unscoped : self.where(conditions)
|
47
|
+
|
48
|
+
if order_by
|
49
|
+
list.order_by(order_by)
|
50
|
+
else
|
51
|
+
list.order_by(metadata.order)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias :ordered :filtered # backward compatibility + semantic purpose
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
klass.accepts_nested_attributes_for rule['name'], allow_destroy: true
|
60
|
+
|
61
|
+
if rule['required']
|
62
|
+
klass.validates_collection_size_of rule['name'], minimum: 1, message: :at_least_one_element, on: :update
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Integer
|
4
|
+
|
5
|
+
module Field; end
|
6
|
+
|
7
|
+
module Target
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
# Add a integer field
|
13
|
+
#
|
14
|
+
# @param [ Class ] klass The class to modify
|
15
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
16
|
+
#
|
17
|
+
def apply_integer_custom_field(klass, rule)
|
18
|
+
name = rule['name']
|
19
|
+
|
20
|
+
klass.field name, type: ::Integer, localize: rule['localized'] || false
|
21
|
+
klass.validates_presence_of name if rule['required']
|
22
|
+
klass.validates name, numericality: { only_integer: true }, if: ->(x){ rule['required'] }
|
23
|
+
end
|
24
|
+
|
25
|
+
# Build a hash storing the raw value for
|
26
|
+
# a string custom field of an instance.
|
27
|
+
#
|
28
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
29
|
+
# @param [ String ] name The name of the string custom field
|
30
|
+
#
|
31
|
+
# @return [ Hash ] field name => raw value
|
32
|
+
#
|
33
|
+
def integer_attribute_get(instance, name)
|
34
|
+
self.default_attribute_get(instance, name)
|
35
|
+
end
|
36
|
+
|
37
|
+
# Set the value for the instance and the string field specified by
|
38
|
+
# the 2 params.
|
39
|
+
#
|
40
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
41
|
+
# @param [ String ] name The name of the string custom field
|
42
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
43
|
+
#
|
44
|
+
def integer_attribute_set(instance, name, attributes)
|
45
|
+
self.default_attribute_set(instance, name, attributes)
|
46
|
+
end
|
47
|
+
|
48
|
+
end # ClassMethods
|
49
|
+
|
50
|
+
end # Target
|
51
|
+
|
52
|
+
end # Integer
|
53
|
+
end # Types
|
54
|
+
end # CustomFields
|