custom_fields 2.3.3 → 2.4.0.rc5

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
2
  SHA1:
3
- metadata.gz: 4c97a9164b3261a278b1f3301269d033c3745924
4
- data.tar.gz: ab3202cae5b8b60bfcb29d417d405c9eeadefb9d
3
+ metadata.gz: c59df522a773c83afb22a2378a12e14dce6cd8b3
4
+ data.tar.gz: d74bbf77539f97cc86e993ff8ae0cecdd21f8bc2
5
5
  SHA512:
6
- metadata.gz: ffab683cf013c7a8370f77d3f09804217e5710c89f2d560f2a1e2fb56df8cab72887667e37a5ba75fa8ae2c8979ac9b1456ab5d5ec839e06cbe9849ca10f98d3
7
- data.tar.gz: 24302382c64724b139af6d0fd6d1d9eac2e411f43ca255df746cefff608b24ec3f8abc5f96289eba5f7d264c886d3c3cec2b414f6142af5753e96b779e7699f3
6
+ metadata.gz: 3b1b96bc1e316bb42c4760444a358e38ae77ea07adcb9448b2defb12695505e9b6afa205f28ec8f6a7e292924fc39c10e6cff255ea8717d464b88acfdac32354
7
+ data.tar.gz: e6a53bca57082c639dccca3b06aed49a952ae59482918b583de4db343fd13b06ca97d18f537c8a89244ae82ea373d4e9e7e729decc9d83b2963d0b196f5790ea
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2013-2015, Didier Lafforgue
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7
+ the Software, and to permit persons to whom the Software is furnished to do so,
8
+ subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
15
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
16
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ [CustomFields]
2
+ ==============
3
+
4
+ [![Travis CI Status][Travis CI Status]][Travis CI]
5
+ [![Gemnasium Status][Gemnasium Status]][Gemnasium]
6
+
7
+ Manage custom fields to a Mongoid document or a collection. This module is one of the core features we implemented in
8
+ our custom CMS, named LocomotiveCMS. Basically, its aim is to provide to editors a way to manage extra fields to a
9
+ Mongoid document through, for instance, a web UI.
10
+
11
+ The main goals:
12
+
13
+ * Offering a very secure way to add, edit and delete extra fields to a Mongoid document.
14
+ * Scoping the modifications added to a Mongoid document, so that other documents of the same class won't be updated.
15
+
16
+ Requirements
17
+ ------------
18
+
19
+ * MongoDB 2.x
20
+ * Mongoid 4.x
21
+ * ActiveSupport 4.2.x
22
+
23
+ Examples
24
+ --------
25
+
26
+ ### On a `has_many` relationship
27
+
28
+ ```ruby
29
+ class Company
30
+ include CustomFields::Source
31
+
32
+ has_many :employees
33
+
34
+ custom_fields_for :employees
35
+ end
36
+
37
+ class Employee
38
+ include CustomFields::Target
39
+
40
+ field :name, String
41
+
42
+ belongs_to :company, inverse_of: :employees
43
+ end
44
+
45
+ company = Company.new
46
+ company.employees_custom_fields.build label: 'His/her position', name: 'position', type: 'string', required: true
47
+
48
+ company.save
49
+
50
+ company.employees.build name: 'Michael Scott', position: 'Regional manager'
51
+
52
+ another_company = Company.new
53
+ employee = another_company.employees.build
54
+ employee.position # Returns a `not defined method` error
55
+ ```
56
+
57
+ ### On the class itself
58
+
59
+ **IN PROGRESS**
60
+
61
+ ```ruby
62
+ class Company
63
+ custom_fields_for_itself
64
+ end
65
+
66
+ company = Company.new
67
+ company.self_metadata_custom_fields.build label: 'Shipping Address', name: 'address', type: 'text'
68
+
69
+ company.save
70
+
71
+ company.self_metadata.address = '700 S Laflin, 60607 Chicago'
72
+
73
+ another_company = Company.new
74
+ other_company.self_metadata.address # Returns a `not defined method` error
75
+ ```
76
+
77
+ Development
78
+ -----------
79
+
80
+ ### Run specs
81
+
82
+ Run `rspec` or `rake`.
83
+
84
+ ### Test Coverage
85
+
86
+ Run `COVERAGE=true rspec` or `COVERAGE=true rake`.
87
+
88
+ Contact
89
+ -------
90
+
91
+ Feel free to contact me at didier at nocoffee dot fr.
92
+
93
+ License
94
+ -------
95
+
96
+ Copyright (c) 2013-2015 NoCoffee, released under the [MIT License (MIT)], see [LICENSE].
97
+
98
+ [CustomFields]: https://github.com/locomotivecms/custom_fields "Custom fields extension for Mongoid."
99
+ [Gemnasium]: https://gemnasium.com/locomotivecms/custom_fields "CustomFields at Gemnasium"
100
+ [Gemnasium Status]: https://img.shields.io/gemnasium/locomotivecms/custom_fields.svg?style=flat "Gemnasium Status"
101
+ [LICENSE]: https://raw.githubusercontent.com/locomotivecms/custom_fields/master/LICENSE "License"
102
+ [MIT License (MIT)]: http://opensource.org/licenses/MIT "The MIT License (MIT)"
103
+ [Travis CI]: https://travis-ci.org/locomotivecms/custom_fields "CustomFields at Travis CI"
104
+ [Travis CI Status]: https://img.shields.io/travis/locomotivecms/custom_fields.svg?style=flat "Travis CI Status"
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Mongoid #:nodoc:
3
2
 
4
3
  module Document #:nodoc:
@@ -1,20 +1,18 @@
1
- # encoding: utf-8
2
1
  module Mongoid #:nodoc:
3
2
 
4
3
  # Instantiates documents that came from the database.
5
4
  module Factory
6
5
 
7
- def from_db_with_custom_fields(klass, attributes = {}, criteria_instance_id = nil)
6
+ def from_db_with_custom_fields(klass, attributes = nil, selected_fields = nil)
8
7
  if klass.with_custom_fields?
9
8
  klass.klass_with_custom_fields(attributes['custom_fields_recipe'])
10
9
  end
11
- from_db_without_custom_fields(klass, attributes, criteria_instance_id)
10
+
11
+ from_db_without_custom_fields(klass, attributes, selected_fields)
12
12
  end
13
13
 
14
14
  # equivalent for "alias_method_chain :from_db, :custom_fields"
15
15
  alias_method :from_db_without_custom_fields, :from_db unless method_defined?(:from_db_without_custom_fields)
16
16
  alias_method :from_db, :from_db_with_custom_fields
17
-
18
17
  end
19
-
20
18
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Mongoid #:nodoc:
3
2
  module Fields #:nodoc:
4
3
 
@@ -23,7 +22,18 @@ module Mongoid #:nodoc:
23
22
  elsif object.has_key?(locale.to_s)
24
23
  object[locale.to_s]
25
24
  elsif I18n.fallbacks?
26
- object[I18n.fallbacks[locale].map(&:to_s).find { |loc| !object[loc].nil? }]
25
+ lookup_with_fallback(object)
26
+ else
27
+ nil
28
+ end
29
+ end
30
+
31
+ def lookup_with_fallback(object)
32
+ fallback_locales = I18n.fallbacks[locale].try(:map, &:to_s)
33
+
34
+ if fallback_locales
35
+ _locale = fallback_locales.find { |loc| !object[loc].nil? }
36
+ object[_locale]
27
37
  else
28
38
  nil
29
39
  end
@@ -1,22 +1,15 @@
1
- # encoding: utf-8
2
1
  module Mongoid # :nodoc:
3
2
  module Relations #:nodoc:
4
3
  module Referenced #:nodoc:
5
4
 
6
5
  class In < Relations::One
7
-
8
6
  class << self
9
-
10
7
  def valid_options_with_parent_class
11
8
  valid_options_without_parent_class.push :custom_fields_parent_klass
12
9
  end
13
-
14
10
  alias_method_chain :valid_options, :parent_class
15
-
16
11
  end
17
-
18
12
  end
19
-
20
13
  end
21
14
  end
22
15
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Mongoid #:nodoc:
3
2
  module Relations #:nodoc:
4
3
  module Referenced #:nodoc:
@@ -7,22 +6,17 @@ module Mongoid #:nodoc:
7
6
  # one-to-many between documents in different collections.
8
7
  class Many < Relations::Many
9
8
 
10
- def build_with_custom_fields(attributes = {}, options = {}, type = nil)
11
- if base.respond_to?(:custom_fields_for?) && base.custom_fields_for?(metadata.name)
9
+ def build_with_custom_fields(attributes = {}, type = nil)
10
+ if base.respond_to?(:custom_fields_for?) && base.custom_fields_for?(relation_metadata.name)
12
11
  # all the information about how to build the custom class are stored here
13
- recipe = base.custom_fields_recipe_for(metadata.name)
14
-
12
+ recipe = base.custom_fields_recipe_for(relation_metadata.name)
15
13
  attributes ||= {}
16
-
17
14
  attributes.merge!(custom_fields_recipe: recipe)
18
-
19
15
  # build the class with custom_fields for the first time
20
- type = metadata.klass.klass_with_custom_fields(recipe)
16
+ type = relation_metadata.klass.klass_with_custom_fields(recipe)
21
17
  end
22
- build_without_custom_fields(attributes, options, type)
23
-
18
+ build_without_custom_fields(attributes, type)
24
19
  end
25
-
26
20
  alias_method_chain :build, :custom_fields
27
21
 
28
22
  # new should point to the new build method
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Mongoid
3
2
  module Validations
4
3
 
@@ -13,7 +12,7 @@ module Mongoid
13
12
  #
14
13
  # validates_collection_size_of :addresses, in: 1..10
15
14
  # end
16
- class CollectionSizeValidator < LengthValidator
15
+ class CollectionSizeValidator < Mongoid::Validatable::LengthValidator
17
16
 
18
17
  def validate_each_with_collection(record, attribute, value)
19
18
  value = collection_to_size(record, attribute)
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
- module Validations
2
+ module Validatable
3
3
  module Macros
4
4
  extend ActiveSupport::Concern
5
5
 
@@ -22,4 +22,4 @@ module Mongoid
22
22
 
23
23
  end
24
24
  end
25
- end
25
+ end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Origin
3
2
 
4
3
  # This is a smart hash for use with options and selectors.
@@ -6,7 +6,7 @@ module CustomFields
6
6
  include ::Mongoid::Timestamps
7
7
 
8
8
  AVAILABLE_TYPES = %w(default string text email date date_time boolean file select float integer
9
- money tags relationship_default belongs_to has_many many_to_many)
9
+ money tags color relationship_default belongs_to has_many many_to_many)
10
10
 
11
11
  ## types ##
12
12
  AVAILABLE_TYPES.each do |type|
@@ -27,7 +27,7 @@ module CustomFields
27
27
  validates_presence_of :label, :type
28
28
  validates_exclusion_of :name, in: lambda { |f| CustomFields.options[:reserved_names].map(&:to_s) }
29
29
  validates_inclusion_of :type, in: AVAILABLE_TYPES, allow_blank: true
30
- validates_format_of :name, with: /^[a-z]([A-Za-z0-9_]+)?$/
30
+ validates_format_of :name, with: /^[a-z]([A-Za-z0-9_]+)?$/, multiline: true
31
31
  validate :uniqueness_of_label_and_name
32
32
 
33
33
  ## callbacks ##
@@ -98,7 +98,8 @@ module CustomFields
98
98
  end
99
99
 
100
100
  def siblings
101
- self._parent.send(self.metadata.name)
101
+ # binding.pry
102
+ self._parent.send(self.relation_metadata.name)
102
103
  end
103
104
 
104
105
  end
@@ -36,7 +36,7 @@ module CustomFields
36
36
  def klass_with_custom_fields(name)
37
37
  # Rails.logger.debug "[CustomFields] klass_with_custom_fields #{self.send(name).metadata.klass} / #{self.send(name).metadata[:old_klass]}" if defined?(Rails) # DEBUG
38
38
  recipe = self.custom_fields_recipe_for(name)
39
- _metadata = self.send(name).metadata
39
+ _metadata = self.send(name).relation_metadata
40
40
  target = _metadata[:original_klass] || _metadata.klass # avoid to use an already enhanced klass
41
41
  target.klass_with_custom_fields(recipe)
42
42
  end
@@ -66,7 +66,7 @@ module CustomFields
66
66
  'name' => "#{self.relations[name.to_s].class_name.demodulize}#{self._id}",
67
67
  'rules' => self.ordered_custom_fields(name).map(&:to_recipe),
68
68
  'version' => self.custom_fields_version(name),
69
- 'model_name' => self.relations[name.to_s].class_name.constantize.model_name
69
+ 'model_name' => self.relations[name.to_s].class_name.constantize.model_name.to_s
70
70
  }
71
71
  end
72
72
 
@@ -98,13 +98,13 @@ module CustomFields
98
98
  def refresh_metadata_with_custom_fields(name)
99
99
  return if !self.persisted? || self.send(:"#{name}_custom_fields").blank? # do not generate a klass without all the information
100
100
 
101
- old_metadata = self.send(name).metadata
101
+ old_metadata = self.send(name).relation_metadata
102
102
 
103
103
  # puts "old_metadata = #{old_metadata.klass.inspect} / #{old_metadata.object_id.inspect}" # DEBUG
104
104
 
105
105
  # puts "[CustomFields] refresh_metadata_with_custom_fields, #{name.inspect}, self = #{self.inspect}"
106
106
 
107
- self.send(name).metadata = old_metadata.clone.tap do |metadata|
107
+ self.send(name).__metadata = old_metadata.clone.tap do |metadata|
108
108
  # Rails.logger.debug "[CustomFields] refresh_metadata_with_custom_fields #{metadata.klass}" if defined?(Rails) # DEBUG
109
109
 
110
110
  # backup the current klass
@@ -175,8 +175,12 @@ module CustomFields
175
175
  # http://docs.mongodb.org/manual/reference/method/db.collection.update/#update-parameter
176
176
  # The <update> document must contain only update operator expressions.
177
177
  %w(set unset rename).each do |operation_name|
178
- _operations = { "$#{operation_name}" => operations.delete("$#{operation_name}") }
179
- collection.find(selector).update _operations, multi: true
178
+ _fields = operations.delete("$#{operation_name}")
179
+
180
+ next if _fields.empty?
181
+
182
+ _operation = { "$#{operation_name}" => _fields }
183
+ collection.find(selector).update _operation, multi: true
180
184
  end
181
185
  end
182
186
 
@@ -7,8 +7,8 @@ module CustomFields
7
7
  included do
8
8
 
9
9
  ## types ##
10
- %w(default string text email date date_time boolean file select float integer money
11
- belongs_to has_many many_to_many tags).each do |type|
10
+ %w(default string text email date date_time boolean file select
11
+ float integer money color belongs_to has_many many_to_many tags).each do |type|
12
12
  include "CustomFields::Types::#{type.camelize}::Target".constantize
13
13
  end
14
14
 
@@ -37,7 +37,7 @@ module CustomFields
37
37
  self.custom_fields_recipe['rules'].map do |rule|
38
38
  case rule['type'].to_sym
39
39
  when :date, :date_time, :money then "formatted_#{rule['name']}"
40
- when :file then [rule['name'], "remove_#{rule['name']}"]
40
+ when :file then [rule['name'], "remove_#{rule['name']}", "remote_#{rule['name']}_url"]
41
41
  when :select, :belongs_to then ["#{rule['name']}_id", "position_in_#{rule['name']}"]
42
42
  when :has_many, :many_to_many then nil
43
43
  else
@@ -0,0 +1,55 @@
1
+ module CustomFields
2
+
3
+ module Types
4
+
5
+ module Color
6
+
7
+ module Field; end
8
+
9
+ module Target
10
+
11
+ extend ActiveSupport::Concern
12
+
13
+ module ClassMethods
14
+
15
+ # Add a color 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_color_custom_field(klass, rule)
21
+ apply_custom_field(klass, rule)
22
+ end
23
+
24
+ # Build a hash storing the raw value for
25
+ # a color 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 color custom field
29
+ #
30
+ # @return [ Hash ] field name => raw value
31
+ #
32
+ def color_attribute_get(instance, name)
33
+ self.default_attribute_get(instance, name)
34
+ end
35
+
36
+ # Set the value for the instance and the color 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 color custom field
41
+ # @param [ Hash ] attributes The attributes used to fetch the values
42
+ #
43
+ def color_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
@@ -1,11 +1,7 @@
1
1
  module CustomFields
2
-
3
2
  module Types
4
-
5
3
  module HasMany
6
-
7
4
  module Field
8
-
9
5
  extend ActiveSupport::Concern
10
6
 
11
7
  included do
@@ -17,15 +13,11 @@ module CustomFields
17
13
  def has_many_is_relationship?
18
14
  self.type == 'has_many'
19
15
  end
20
-
21
16
  end
22
-
23
17
  end
24
18
 
25
19
  module Target
26
-
27
20
  extend ActiveSupport::Concern
28
-
29
21
  module ClassMethods
30
22
 
31
23
  # Adds a has_many relationship between 2 mongoid models
@@ -40,7 +32,7 @@ module CustomFields
40
32
  _order_by = rule['order_by'] || position_name.to_sym.asc
41
33
  _inverse_of = rule['inverse_of'].blank? ? nil : rule['inverse_of'] # an empty String can cause weird behaviours
42
34
 
43
- klass.has_many rule['name'], class_name: rule['class_name'], inverse_of: _inverse_of, order: _order_by do
35
+ klass.has_many rule['name'], class_name: rule['class_name'], inverse_of: _inverse_of, order: _order_by, validate: false do
44
36
 
45
37
  def filtered(conditions = {}, order_by = nil)
46
38
  list = conditions.empty? ? self.unscoped : self.where(conditions)
@@ -48,12 +40,10 @@ module CustomFields
48
40
  if order_by
49
41
  list.order_by(order_by)
50
42
  else
51
- list.order_by(metadata.order)
43
+ list.order_by(relation_metadata.order)
52
44
  end
53
45
  end
54
-
55
46
  alias :ordered :filtered # backward compatibility + semantic purpose
56
-
57
47
  end
58
48
 
59
49
  klass.accepts_nested_attributes_for rule['name'], allow_destroy: true
@@ -62,13 +52,8 @@ module CustomFields
62
52
  klass.validates_collection_size_of rule['name'], minimum: 1, message: :at_least_one_element, on: :update
63
53
  end
64
54
  end
65
-
66
55
  end
67
-
68
56
  end
69
-
70
57
  end
71
-
72
58
  end
73
-
74
59
  end
@@ -1,15 +1,10 @@
1
1
  module CustomFields
2
-
3
2
  module Types
4
-
5
3
  module ManyToMany
6
-
7
4
  module Field
8
-
9
5
  extend ActiveSupport::Concern
10
6
 
11
7
  included do
12
-
13
8
  def many_to_many_to_recipe
14
9
  { 'class_name' => self.class_name, 'inverse_of' => self.inverse_of, 'order_by' => self.order_by }
15
10
  end
@@ -17,13 +12,10 @@ module CustomFields
17
12
  def many_to_many_is_relationship?
18
13
  self.type == 'many_to_many'
19
14
  end
20
-
21
15
  end
22
-
23
16
  end
24
17
 
25
18
  module Target
26
-
27
19
  extend ActiveSupport::Concern
28
20
 
29
21
  module ClassMethods
@@ -36,11 +28,7 @@ module CustomFields
36
28
  def apply_many_to_many_custom_field(klass, rule)
37
29
  # puts "#{klass.inspect}.many_to_many #{rule['name'].inspect}, class_name: #{rule['class_name'].inspect} / #{rule['order_by']}" # DEBUG
38
30
 
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
31
+ klass.has_and_belongs_to_many rule['name'], class_name: rule['class_name'], inverse_of: rule['inverse_of'], validate: false, order: rule['order_by'] do
44
32
 
45
33
  def filtered(conditions = {}, order_by = nil)
46
34
  list = conditions.empty? ? self : self.where(conditions)
@@ -48,15 +36,30 @@ module CustomFields
48
36
  if order_by
49
37
  list.order_by(order_by)
50
38
  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) }
39
+ _naturally_ordered(list, order_by)
55
40
  end
56
41
  end
57
42
 
58
43
  alias :ordered :filtered # backward compatibility + semantic purpose
59
44
 
45
+ def _naturally_ordered(criteria, order_by = nil)
46
+ # use the natural order given by the initial array (ex: project_ids).
47
+ # Warning: it returns an array and not a criteria object meaning it breaks the chain
48
+ ids = base.send(relation_metadata.key.to_sym)
49
+ criteria.entries.sort { |a, b| ids.index(a.id) <=> ids.index(b.id) }
50
+ end
51
+
52
+ def pluck_with_natural_order(*attributes)
53
+ criteria = self.only([:_id] + [*attributes])
54
+ _naturally_ordered(criteria).map do |entry|
55
+ if attributes.size == 1
56
+ entry.public_send(attributes.first.to_sym)
57
+ else
58
+ attributes.map { |name| entry.public_send(name.to_sym) }
59
+ end
60
+ end
61
+ end
62
+
60
63
  end
61
64
 
62
65
  if rule['required']
@@ -72,4 +75,4 @@ module CustomFields
72
75
 
73
76
  end
74
77
 
75
- end
78
+ end
@@ -21,7 +21,7 @@ module CustomFields
21
21
  end
22
22
 
23
23
  def check_currency
24
- ::Money::Currency.find( self.default_currency )
24
+ ::Money::Currency.find(self.default_currency)
25
25
  end
26
26
 
27
27
  end # included
@@ -71,18 +71,18 @@ module CustomFields
71
71
  klass.field names[:currency_field], type: ::String, localize: false
72
72
 
73
73
  # getters and setters
74
- klass.send( :define_method, name ) { _get_money(names) }
75
- klass.send( :define_method, :"#{name}=" ) { |value| _set_money(value, names) }
74
+ klass.send(:define_method, name) { _get_money(names) }
75
+ klass.send(:define_method, :"#{name}=") { |value| _set_money(value, names) }
76
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) }
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
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'] }
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
82
 
83
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']
84
+ klass.validate { _check_money(names) } if rule['required']
85
+ klass.validates_presence_of(names[:cents_field], names[:currency_field]) if rule['required']
86
86
  klass.validates_numericality_of names[:cents_field], only_integer: true, if: names[:cents_field]
87
87
 
88
88
  end
@@ -106,38 +106,38 @@ module CustomFields
106
106
 
107
107
  protected
108
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] )
109
+ def _set_money_defaults(names)
110
+ ::Monetize.assume_from_symbol = self.send(names[:allow_currency_from_symbol])
111
+ ::Money.default_currency = self.send(names[:default_currency])
112
112
  end
113
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 )
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
117
  end
118
118
 
119
- def _check_money( names )
119
+ def _check_money(names)
120
120
  if [nil, ''].include? self.read_attribute.names[:cents_field]
121
121
  raise ArgumentError.new 'Unrecognized amount'
122
122
  end
123
- _get_money( names )
123
+ _get_money(names)
124
124
  rescue
125
- self.errors.add( names[:name], "#{$!}" )
125
+ self.errors.add(names[:name], "#{$!}")
126
126
  false
127
127
  end
128
128
 
129
- def _set_money( _money, names )
129
+ def _set_money(_money, names)
130
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 )
131
+ _set_money_defaults(names)
132
+ money = _money.kind_of?(Money) ? _money : ::Monetize.parse(_money)
133
+ self.write_attribute(names[:cents_field], money.cents)
134
+ self.write_attribute(names[:currency_field], money.currency.iso_code)
135
135
  rescue
136
- self.errors.add( names[:name], "#{$!}" )
136
+ self.errors.add(names[:name], "#{$!}")
137
137
  end
138
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
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
141
  end
142
142
 
143
143
  end
@@ -67,7 +67,7 @@ module CustomFields
67
67
  def apply_select_custom_field(klass, rule)
68
68
  name, base_collection_name = rule['name'], "#{rule['name']}_options".to_sym
69
69
 
70
- klass.field :"#{name}_id", type: Moped::BSON::ObjectId, localize: rule['localized'] || false
70
+ klass.field :"#{name}_id", type: BSON::ObjectId, localize: rule['localized'] || false
71
71
 
72
72
  klass.cattr_accessor "_raw_#{base_collection_name}"
73
73
  klass.send :"_raw_#{base_collection_name}=", rule['select_options'].sort { |a, b| a['position'] <=> b['position'] }
@@ -134,8 +134,8 @@ module CustomFields
134
134
  #
135
135
  def group_by_select_option(name, order_by = nil)
136
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}
137
+ groups = self.each.group_by { |x| x.send(name_id) }.map do |(k, v)|
138
+ { name_id => k, 'group' => v }
139
139
  end
140
140
 
141
141
  _select_options(name).map do |option|
@@ -1,6 +1,5 @@
1
- # encoding: utf-8
2
1
  module CustomFields #:nodoc
3
2
 
4
- VERSION = '2.3.3'
3
+ VERSION = '2.4.0.rc5'
5
4
 
6
5
  end
data/lib/custom_fields.rb CHANGED
@@ -2,12 +2,14 @@ $:.unshift File.expand_path(File.dirname(__FILE__))
2
2
 
3
3
  require 'active_support'
4
4
  require 'carrierwave/mongoid'
5
- require 'money'
5
+ require 'monetize'
6
+
7
+ Money.use_i18n = false
6
8
 
7
9
  module CustomFields
8
10
 
9
11
  @@options = {
10
- reserved_names: Mongoid.destructive_fields + %w(id _id send class),
12
+ reserved_names: Mongoid.destructive_fields + %w(id _id send class destroy),
11
13
  default_currency: 'EUR'
12
14
  }
13
15
 
@@ -46,6 +48,7 @@ end
46
48
  types/integer
47
49
  types/float
48
50
  types/money
51
+ types/color
49
52
  types/relationship_default
50
53
  types/belongs_to
51
54
  types/has_many
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: custom_fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.3
4
+ version: 2.4.0.rc5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Didier Lafforgue
@@ -16,114 +16,128 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.1.6
19
+ version: 4.0.2
20
20
  type: :runtime
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: 3.1.6
26
+ version: 4.0.2
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: carrierwave-mongoid
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 3.2.21
33
+ version: 0.7.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 3.2.21
40
+ version: 0.7.1
41
41
  - !ruby/object:Gem::Dependency
42
- name: carrierwave-mongoid
42
+ name: activesupport
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.0
47
+ version: 4.2.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.6.0
54
+ version: 4.2.1
55
55
  - !ruby/object:Gem::Dependency
56
- name: money
56
+ name: monetize
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '5.0'
61
+ version: 1.1.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '5.0'
68
+ version: 1.1.0
69
69
  - !ruby/object:Gem::Dependency
70
- name: yard
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.7.3
75
+ version: '10.4'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.7.3
82
+ version: '10.4'
83
83
  - !ruby/object:Gem::Dependency
84
- name: mocha
84
+ name: pry
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.9.12
89
+ version: 0.10.1
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.9.12
96
+ version: 0.10.1
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rspec
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '2.6'
103
+ version: 3.1.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '2.6'
110
+ version: 3.1.0
111
111
  - !ruby/object:Gem::Dependency
112
- name: simplecov
112
+ name: rspec-its
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: 0.6.1
117
+ version: 1.1.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: 0.6.1
124
+ version: 1.1.0
125
125
  - !ruby/object:Gem::Dependency
126
- name: database_cleaner
126
+ name: mocha
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 1.1.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 1.1.0
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
@@ -137,45 +151,58 @@ dependencies:
137
151
  - !ruby/object:Gem::Version
138
152
  version: 0.9.1
139
153
  - !ruby/object:Gem::Dependency
140
- name: pry
154
+ name: database_cleaner
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - ">="
157
+ - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '0'
159
+ version: 1.3.0
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
- - - ">="
164
+ - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '0'
166
+ version: 1.3.0
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: RedCloth
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - "~>"
158
172
  - !ruby/object:Gem::Version
159
- version: 4.2.8
173
+ version: 4.2.9
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 4.2.9
181
+ - !ruby/object:Gem::Dependency
182
+ name: yard
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.8.7
160
188
  type: :development
161
189
  prerelease: false
162
190
  version_requirements: !ruby/object:Gem::Requirement
163
191
  requirements:
164
192
  - - "~>"
165
193
  - !ruby/object:Gem::Version
166
- version: 4.2.8
167
- description: Manage custom fields to a mongoid document or a collection. This module
168
- is one of the core features we implemented in our custom cms named Locomotive.
169
- email:
170
- - didier@nocoffee.fr
194
+ version: 0.8.7
195
+ description: Manage custom fields to a Mongoid document or a collection. This module
196
+ is one of the core features we implemented in our custom CMS, named LocomotiveCMS.
197
+ email: didier@nocoffee.fr
171
198
  executables: []
172
199
  extensions: []
173
200
  extra_rdoc_files:
174
- - MIT-LICENSE
175
- - README.textile
201
+ - LICENSE
202
+ - README.md
176
203
  files:
177
- - MIT-LICENSE
178
- - README.textile
204
+ - LICENSE
205
+ - README.md
179
206
  - config/locales/de.yml
180
207
  - config/locales/en.yml
181
208
  - config/locales/fr.yml
@@ -200,6 +227,7 @@ files:
200
227
  - lib/custom_fields/target_helpers.rb
201
228
  - lib/custom_fields/types/belongs_to.rb
202
229
  - lib/custom_fields/types/boolean.rb
230
+ - lib/custom_fields/types/color.rb
203
231
  - lib/custom_fields/types/date.rb
204
232
  - lib/custom_fields/types/date_time.rb
205
233
  - lib/custom_fields/types/default.rb
@@ -216,8 +244,9 @@ files:
216
244
  - lib/custom_fields/types/tags.rb
217
245
  - lib/custom_fields/types/text.rb
218
246
  - lib/custom_fields/version.rb
219
- homepage: http://github.com/locomotivecms/custom_fields
220
- licenses: []
247
+ homepage: https://github.com/locomotivecms/custom_fields
248
+ licenses:
249
+ - MIT
221
250
  metadata: {}
222
251
  post_install_message:
223
252
  rdoc_options: []
@@ -225,18 +254,18 @@ require_paths:
225
254
  - lib
226
255
  required_ruby_version: !ruby/object:Gem::Requirement
227
256
  requirements:
228
- - - ">="
257
+ - - "~>"
229
258
  - !ruby/object:Gem::Version
230
- version: '0'
259
+ version: '2.1'
231
260
  required_rubygems_version: !ruby/object:Gem::Requirement
232
261
  requirements:
233
- - - ">="
262
+ - - "~>"
234
263
  - !ruby/object:Gem::Version
235
- version: 1.3.6
264
+ version: '2.4'
236
265
  requirements: []
237
- rubyforge_project: nowarning
238
- rubygems_version: 2.2.0
266
+ rubyforge_project:
267
+ rubygems_version: 2.4.5
239
268
  signing_key:
240
269
  specification_version: 4
241
- summary: Custom fields extension for Mongoid
270
+ summary: Custom fields extension for Mongoid.
242
271
  test_files: []
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2013 [Didier Lafforgue]
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile DELETED
@@ -1,70 +0,0 @@
1
- "!https://secure.travis-ci.org/locomotivecms/custom_fields.png!":http://travis-ci.org/locomotivecms/custom_fields
2
-
3
- h1. CustomFields
4
-
5
- Manage custom fields to a mongoid document or a collection. This module is one of the core features we implemented in our custom cms, LocomotiveCMS.
6
- Basically, its aim is to provide to editors a way to manage extra fields to a Mongoid document through, for instance, a web UI.
7
-
8
- The main goals:
9
-
10
- * offering a very secure way to add / edit / delete extra fields to a Mongoid document
11
- * scoping the modifications added to a Mongoid document so that other documents of the same class won't be updated.
12
-
13
- h2. Requirements
14
-
15
- Ruby 2.1.x, ActiveSupport 3.2.21, MongoDB 2.0 and Mongoid 3.1.3
16
-
17
- h2. Examples
18
-
19
- h3. On a has_many relationship
20
-
21
- bc.. class Company
22
- include CustomFields::Source
23
-
24
- has_many :employees
25
-
26
- custom_fields_for :employees
27
- end
28
-
29
- class Employee
30
- include CustomFields::Target
31
-
32
- field :name, String
33
-
34
- belongs_to :company, :inverse_of => :employees
35
- end
36
-
37
- company = Company.new
38
- company.employees_custom_fields.build :label => 'His/her position', :name => 'position', :type => 'string', :required => true
39
-
40
- company.save
41
-
42
- company.employees.build :name => 'Michael Scott', :position => 'Regional manager'
43
-
44
- another_company = Company.new
45
- employee = another_company.employees.build
46
- employee.position # returns a "not defined method" error
47
-
48
- h3. On the class itself
49
-
50
- [IN PROGRESS]
51
-
52
- bc.. class Company
53
- custom_fields_for_itself
54
- end
55
-
56
- company = Company.new
57
- company.self_metadata_custom_fields.build :label => 'Shipping Address', :name => 'address', :type => 'text'
58
-
59
- company.save
60
-
61
- company.self_metadata.address = '700 S Laflin, 60607 Chicago'
62
-
63
- another_company = Company.new
64
- other_company.self_metadata.address # returns a "not defined method" error
65
-
66
- h2. Contact
67
-
68
- Feel free to contact me at didier at nocoffee dot fr.
69
-
70
- Copyright (c) 2013 NoCoffee, released under the MIT license