gnuside-custom_fields 2.3.1
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 +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,75 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module ManyToMany
|
6
|
+
|
7
|
+
module Field
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
def many_to_many_to_recipe
|
14
|
+
{ 'class_name' => self.class_name, 'inverse_of' => self.inverse_of, 'order_by' => self.order_by }
|
15
|
+
end
|
16
|
+
|
17
|
+
def many_to_many_is_relationship?
|
18
|
+
self.type == 'many_to_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 many_to_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_many_to_many_custom_field(klass, rule)
|
37
|
+
# puts "#{klass.inspect}.many_to_many #{rule['name'].inspect}, class_name: #{rule['class_name'].inspect} / #{rule['order_by']}" # DEBUG
|
38
|
+
|
39
|
+
klass.has_and_belongs_to_many rule['name'], class_name: rule['class_name'], inverse_of: rule['inverse_of'], order: rule['order_by'] do
|
40
|
+
|
41
|
+
# def at_least_one_element?
|
42
|
+
# (base.send(metadata.key.to_sym).try(:size) || 0) > 0
|
43
|
+
# end
|
44
|
+
|
45
|
+
def filtered(conditions = {}, order_by = nil)
|
46
|
+
list = conditions.empty? ? self : self.where(conditions)
|
47
|
+
|
48
|
+
if order_by
|
49
|
+
list.order_by(order_by)
|
50
|
+
else
|
51
|
+
# use the natural order given by the initial array (ex: project_ids).
|
52
|
+
# Warning: it returns an array and not a criteria object meaning it breaks the chain
|
53
|
+
ids = base.send(metadata.key.to_sym)
|
54
|
+
list.entries.sort { |a, b| ids.index(a.id) <=> ids.index(b.id) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
alias :ordered :filtered # backward compatibility + semantic purpose
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
if rule['required']
|
63
|
+
klass.validates_collection_size_of rule['name'], minimum: 1, message: :at_least_one_element
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Money
|
4
|
+
|
5
|
+
module Field
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# allow_currency_from_symbol means that the user is able
|
10
|
+
# to provide another currency instead of the the default
|
11
|
+
# e.g. default is 'EUR' and User sets '100.11 USD'
|
12
|
+
field :default_currency
|
13
|
+
field :allow_currency_from_symbol, type: ::Boolean, default: false
|
14
|
+
|
15
|
+
before_validation :set_default
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def set_default
|
20
|
+
self.default_currency ||= CustomFields.options[:default_currency]
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_currency
|
24
|
+
::Money::Currency.find( self.default_currency )
|
25
|
+
end
|
26
|
+
|
27
|
+
end # included
|
28
|
+
|
29
|
+
def money_to_recipe
|
30
|
+
{ 'default_currency' => self.default_currency,
|
31
|
+
'allow_currency_from_symbol' => self.allow_currency_from_symbol }
|
32
|
+
end
|
33
|
+
|
34
|
+
def money_as_json(options = {})
|
35
|
+
money_to_recipe
|
36
|
+
end
|
37
|
+
|
38
|
+
end # module Field
|
39
|
+
|
40
|
+
|
41
|
+
module Target
|
42
|
+
extend ActiveSupport::Concern
|
43
|
+
|
44
|
+
module ClassMethods
|
45
|
+
|
46
|
+
# Adds a Money field
|
47
|
+
#
|
48
|
+
# uses the money gem (https://github.com/RubyMoney/money)
|
49
|
+
#
|
50
|
+
# @param [ Class ] klass The class to modify
|
51
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
52
|
+
#
|
53
|
+
# if allow_currency_from_symbol is set the formatted_name_field will return the amount
|
54
|
+
# and the currency
|
55
|
+
|
56
|
+
def apply_money_custom_field(klass, rule)
|
57
|
+
|
58
|
+
# the field names
|
59
|
+
name = rule['name']
|
60
|
+
names = {
|
61
|
+
name: name.to_sym,
|
62
|
+
cents_field: "#{name}_cents".to_sym,
|
63
|
+
currency_field: "#{name}_currency".to_sym,
|
64
|
+
formatted_name_field: "formatted_#{name}".to_sym,
|
65
|
+
allow_currency_from_symbol: "#{name}_allow_currency_from_symbol".to_sym,
|
66
|
+
default_currency: "#{name}_default_currency".to_sym
|
67
|
+
}
|
68
|
+
|
69
|
+
# fields
|
70
|
+
klass.field names[:cents_field], type: ::Integer, localize: false
|
71
|
+
klass.field names[:currency_field], type: ::String, localize: false
|
72
|
+
|
73
|
+
# getters and setters
|
74
|
+
klass.send( :define_method, name ) { _get_money(names) }
|
75
|
+
klass.send( :define_method, :"#{name}=" ) { |value| _set_money(value, names) }
|
76
|
+
|
77
|
+
klass.send( :define_method, names[:formatted_name_field] ) { _get_formatted_money(names) }
|
78
|
+
klass.send( :define_method, :"#{names[:formatted_name_field]}=" ) { |value| _set_money(value, names) }
|
79
|
+
|
80
|
+
klass.send( :define_method, names[:allow_currency_from_symbol] ) { rule['allow_currency_from_symbol'] }
|
81
|
+
klass.send( :define_method, names[:default_currency] ) { rule['default_currency'] }
|
82
|
+
|
83
|
+
# validations
|
84
|
+
klass.validate { _check_money( names ) } if rule['required']
|
85
|
+
klass.validates_presence_of( names[:cents_field], names[:currency_field] ) if rule['required']
|
86
|
+
klass.validates_numericality_of names[:cents_field], only_integer: true, if: names[:cents_field]
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def money_attribute_get(instance, name)
|
91
|
+
if value = instance.send(:"formatted_#{name}")
|
92
|
+
{ name => value, "formatted_#{name}" => value }
|
93
|
+
else
|
94
|
+
{}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def money_attribute_set(instance, name, attributes)
|
99
|
+
return unless attributes.key?(name) || attributes.key?("formatted_#{name}")
|
100
|
+
value = attributes[name] || attributes["formatted_#{name}"]
|
101
|
+
instance.send(:"formatted_#{name}=", value)
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
protected
|
108
|
+
|
109
|
+
def _set_money_defaults( names )
|
110
|
+
::Money.assume_from_symbol = self.send( names[:allow_currency_from_symbol] )
|
111
|
+
::Money.default_currency = self.send( names[:default_currency] )
|
112
|
+
end
|
113
|
+
|
114
|
+
def _get_money( names )
|
115
|
+
_set_money_defaults( names )
|
116
|
+
::Money.new( self.read_attribute( names[:cents_field] ), self.read_attribute( names[:currency_field] ) || ::Money.default_currency )
|
117
|
+
end
|
118
|
+
|
119
|
+
def _check_money( names )
|
120
|
+
if [nil, ''].include? self.read_attribute.names[:cents_field]
|
121
|
+
raise ArgumentError.new 'Unrecognized amount'
|
122
|
+
end
|
123
|
+
_get_money( names )
|
124
|
+
rescue
|
125
|
+
self.errors.add( names[:name], "#{$!}" )
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
129
|
+
def _set_money( _money, names )
|
130
|
+
return if _money.blank?
|
131
|
+
_set_money_defaults( names )
|
132
|
+
money = _money.kind_of?( Money ) ? _money : ::Money.parse( _money )
|
133
|
+
self.write_attribute( names[:cents_field], money.cents )
|
134
|
+
self.write_attribute( names[:currency_field], money.currency.iso_code )
|
135
|
+
rescue
|
136
|
+
self.errors.add( names[:name], "#{$!}" )
|
137
|
+
end
|
138
|
+
|
139
|
+
def _get_formatted_money( names )
|
140
|
+
_get_money( names ).format( symbol: self.send( names[:allow_currency_from_symbol] ), no_cents_if_whole: true ) rescue nil
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module RelationshipDefault
|
6
|
+
|
7
|
+
module Field
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
field :class_name
|
14
|
+
field :inverse_of
|
15
|
+
field :order_by
|
16
|
+
|
17
|
+
validates_presence_of :class_name, if: :is_relationship?
|
18
|
+
validate :ensure_class_name_security, if: :is_relationship?
|
19
|
+
|
20
|
+
def is_relationship?
|
21
|
+
method_name = :"#{self.type}_is_relationship?"
|
22
|
+
self.respond_to?(method_name) && self.send(method_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def ensure_class_name_security
|
28
|
+
true
|
29
|
+
# FIXME: to be overridden in the target application
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Select
|
6
|
+
|
7
|
+
class Option
|
8
|
+
|
9
|
+
include Mongoid::Document
|
10
|
+
|
11
|
+
field :name, localize: true
|
12
|
+
field :position, type: ::Integer, default: 0
|
13
|
+
|
14
|
+
embedded_in :custom_field, inverse_of: :select_options
|
15
|
+
|
16
|
+
validates_presence_of :name
|
17
|
+
|
18
|
+
def as_json(options = nil)
|
19
|
+
super methods: %w(_id name position)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
module Field
|
25
|
+
|
26
|
+
extend ActiveSupport::Concern
|
27
|
+
|
28
|
+
included do
|
29
|
+
|
30
|
+
embeds_many :select_options, class_name: 'CustomFields::Types::Select::Option'
|
31
|
+
|
32
|
+
validates_associated :select_options
|
33
|
+
|
34
|
+
accepts_nested_attributes_for :select_options, allow_destroy: true
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def ordered_select_options
|
39
|
+
self.select_options.sort { |a, b| (a.position || 0) <=> (b.position || 0) }.to_a
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_to_recipe
|
43
|
+
{
|
44
|
+
'select_options' => self.ordered_select_options.map do |option|
|
45
|
+
{ '_id' => option._id, 'name' => option.name_translations }
|
46
|
+
end
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
def select_as_json(options = {})
|
51
|
+
{ 'select_options' => self.ordered_select_options.map(&:as_json) }
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
module Target
|
57
|
+
|
58
|
+
extend ActiveSupport::Concern
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
|
62
|
+
# Adds a select field
|
63
|
+
#
|
64
|
+
# @param [ Class ] klass The class to modify
|
65
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
66
|
+
#
|
67
|
+
def apply_select_custom_field(klass, rule)
|
68
|
+
name, base_collection_name = rule['name'], "#{rule['name']}_options".to_sym
|
69
|
+
|
70
|
+
klass.field :"#{name}_id", type: Moped::BSON::ObjectId, localize: rule['localized'] || false
|
71
|
+
|
72
|
+
klass.cattr_accessor "_raw_#{base_collection_name}"
|
73
|
+
klass.send :"_raw_#{base_collection_name}=", rule['select_options'].sort { |a, b| a['position'] <=> b['position'] }
|
74
|
+
|
75
|
+
# other methods
|
76
|
+
klass.send(:define_method, name.to_sym) { _get_select_option(name) }
|
77
|
+
klass.send(:define_method, :"#{name}=") { |value| _set_select_option(name, value) }
|
78
|
+
|
79
|
+
klass.class_eval <<-EOV
|
80
|
+
|
81
|
+
def self.#{base_collection_name}
|
82
|
+
self._select_options('#{name}')
|
83
|
+
end
|
84
|
+
|
85
|
+
EOV
|
86
|
+
|
87
|
+
if rule['required']
|
88
|
+
klass.validates_presence_of name
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Build a hash storing the values (id and option name) for
|
93
|
+
# a select custom field of an instance.
|
94
|
+
#
|
95
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
96
|
+
# @param [ String ] name The name of the select custom field
|
97
|
+
#
|
98
|
+
# @return [ Hash ] fields: <name>: option name, <name>_id: id of the option
|
99
|
+
#
|
100
|
+
def select_attribute_get(instance, name)
|
101
|
+
if value = instance.send(name.to_sym)
|
102
|
+
{
|
103
|
+
name => value,
|
104
|
+
"#{name}_id" => instance.send(:"#{name}_id")
|
105
|
+
}
|
106
|
+
else
|
107
|
+
{}
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Set the value for the instance and the select field specified by
|
112
|
+
# the 2 params.
|
113
|
+
#
|
114
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
115
|
+
# @param [ String ] name The name of the select custom field
|
116
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
117
|
+
#
|
118
|
+
def select_attribute_set(instance, name, attributes)
|
119
|
+
id_or_name = attributes[name] || attributes["#{name}_id"]
|
120
|
+
|
121
|
+
return if id_or_name.nil?
|
122
|
+
|
123
|
+
option = _select_options(name).detect do |option|
|
124
|
+
[option['_id'], option['name']].include?(id_or_name)
|
125
|
+
end
|
126
|
+
|
127
|
+
instance.send(:"#{name}_id=", option.try(:[], '_id'))
|
128
|
+
end
|
129
|
+
|
130
|
+
# Returns a list of documents groupes by select values defined in the custom fields recipe
|
131
|
+
#
|
132
|
+
# @param [ Class ] klass The class to modify
|
133
|
+
# @return [ Array ] An array of hashes (keys: select option and related documents)
|
134
|
+
#
|
135
|
+
def group_by_select_option(name, order_by = nil)
|
136
|
+
name_id = "#{name}_id"
|
137
|
+
groups = self.each.group_by{|x| x.send(name_id)}.map do |(k, v)|
|
138
|
+
{name_id => k, "group" => v}
|
139
|
+
end
|
140
|
+
|
141
|
+
_select_options(name).map do |option|
|
142
|
+
group = groups.detect { |g| g[name_id].to_s == option['_id'].to_s }
|
143
|
+
list = group ? group['group'] : []
|
144
|
+
|
145
|
+
groups.delete(group) if group
|
146
|
+
|
147
|
+
{ name: option['name'], entries: self._order_select_entries(list, order_by) }.with_indifferent_access
|
148
|
+
end.tap do |array|
|
149
|
+
if not groups.empty? # orphan entries ?
|
150
|
+
empty = { name: nil, entries: [] }.with_indifferent_access
|
151
|
+
groups.each do |group|
|
152
|
+
empty[:entries] += group['group']
|
153
|
+
end
|
154
|
+
empty[:entries] = self._order_select_entries(empty[:entries], order_by)
|
155
|
+
array << empty
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def _select_options(name)
|
161
|
+
self.send(:"_raw_#{name}_options").map do |option|
|
162
|
+
|
163
|
+
locale = Mongoid::Fields::I18n.locale.to_s
|
164
|
+
|
165
|
+
name = if !option['name'].respond_to?(:merge)
|
166
|
+
option['name']
|
167
|
+
elsif Mongoid::Fields::I18n.fallbacks?
|
168
|
+
option['name'][Mongoid::Fields::I18n.fallbacks[locale.to_sym].map(&:to_s).find { |loc| !option['name'][loc].nil? }]
|
169
|
+
else
|
170
|
+
option['name'][locale.to_s]
|
171
|
+
end
|
172
|
+
|
173
|
+
{ '_id' => option['_id'], 'name' => name }
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def _order_select_entries(list, order_by = nil)
|
178
|
+
return list if order_by.nil?
|
179
|
+
|
180
|
+
column, direction = order_by.flatten
|
181
|
+
|
182
|
+
list = list.sort { |a, b| (a.send(column) && b.send(column)) ? (a.send(column) || 0) <=> (b.send(column) || 0) : 0 }
|
183
|
+
|
184
|
+
direction == 'asc' ? list : list.reverse
|
185
|
+
|
186
|
+
list
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
def _select_option_id(name)
|
192
|
+
self.send(:"#{name}_id")
|
193
|
+
end
|
194
|
+
|
195
|
+
def _find_select_option(name, id_or_name)
|
196
|
+
self.class._select_options(name).detect do |option|
|
197
|
+
option['name'] == id_or_name || option['_id'].to_s == id_or_name.to_s
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def _get_select_option(name)
|
202
|
+
option = self._find_select_option(name, self._select_option_id(name))
|
203
|
+
option ? option['name'] : nil
|
204
|
+
end
|
205
|
+
|
206
|
+
def _set_select_option(name, value)
|
207
|
+
option = self._find_select_option(name, value)
|
208
|
+
self.send(:"#{name}_id=", option ? option['_id'] : nil)
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module String
|
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_string_custom_field(klass, rule)
|
21
|
+
apply_custom_field(klass, rule)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Build a hash storing the raw value for
|
25
|
+
# a string 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 string custom field
|
29
|
+
#
|
30
|
+
# @return [ Hash ] field name => raw value
|
31
|
+
#
|
32
|
+
def string_attribute_get(instance, name)
|
33
|
+
self.default_attribute_get(instance, name)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Set the value for the instance and the string 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 string custom field
|
41
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
42
|
+
#
|
43
|
+
def string_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,35 @@
|
|
1
|
+
module CustomFields
|
2
|
+
module Types
|
3
|
+
module Tags
|
4
|
+
module Field; end
|
5
|
+
|
6
|
+
module Target
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
|
11
|
+
def apply_tags_custom_field(klass, rule)
|
12
|
+
klass.field rule['name'], localize: rule['localized'] || false, type: Array
|
13
|
+
|
14
|
+
klass.class_eval do
|
15
|
+
define_method("#{rule['name']}=") do |val|
|
16
|
+
#FIXME I would use is_a?(), but it doesn't work in my machine!
|
17
|
+
val = val.split(/ *, */) if val.class.to_s == "String"
|
18
|
+
super(val)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def tags_attribute_get(instance, name)
|
24
|
+
self.default_attribute_get(instance, name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def tags_attribute_set(instance, name, attributes)
|
28
|
+
self.default_attribute_set(instance, name, attributes)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module CustomFields
|
2
|
+
|
3
|
+
module Types
|
4
|
+
|
5
|
+
module Text
|
6
|
+
|
7
|
+
module Field
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
|
13
|
+
field :text_formatting, default: 'html'
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
module Target
|
20
|
+
|
21
|
+
extend ActiveSupport::Concern
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
# Adds a text field (simply a string field)
|
26
|
+
#
|
27
|
+
# @param [ Class ] klass The class to modify
|
28
|
+
# @param [ Hash ] rule It contains the name of the field and if it is required or not
|
29
|
+
#
|
30
|
+
def apply_text_custom_field(klass, rule)
|
31
|
+
apply_custom_field(klass, rule)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Build a hash storing the raw value for
|
35
|
+
# a string 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 string custom field
|
39
|
+
#
|
40
|
+
# @return [ Hash ] field name => raw value
|
41
|
+
#
|
42
|
+
def text_attribute_get(instance, name)
|
43
|
+
default_attribute_get(instance, name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set the value for the instance and the text field specified by
|
47
|
+
# the 2 params.
|
48
|
+
#
|
49
|
+
# @param [ Object ] instance An instance of the class enhanced by the custom_fields
|
50
|
+
# @param [ String ] name The name of the text custom field
|
51
|
+
# @param [ Hash ] attributes The attributes used to fetch the values
|
52
|
+
#
|
53
|
+
def text_attribute_set(instance, name, attributes)
|
54
|
+
self.default_attribute_set(instance, name, attributes)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|