custom_fields 1.0.0.beta.11 → 1.0.0.beta.12

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.
@@ -6,4 +6,6 @@ en:
6
6
  category: Select
7
7
  boolean: Checkbox
8
8
  date: Date
9
- file: File
9
+ file: File
10
+ has_one: Has one
11
+ has_many: Has many
@@ -12,6 +12,8 @@ module CustomFields
12
12
  include Types::Boolean
13
13
  include Types::Date
14
14
  include Types::File
15
+ include Types::HasOne
16
+ include Types::HasMany
15
17
 
16
18
  ## fields ##
17
19
  field :label
@@ -56,9 +58,12 @@ module CustomFields
56
58
  apply_default_type(klass)
57
59
  end
58
60
 
59
- # add validation if required field
60
- if self.required?
61
- klass.validates_presence_of self.safe_alias.to_sym
61
+ validation_method_name = :"add_#{self.safe_kind}_validation"
62
+
63
+ if self.respond_to?(validation_method_name)
64
+ self.send(validation_method_name, klass)
65
+ else
66
+ add_default_validation(klass)
62
67
  end
63
68
  end
64
69
 
@@ -16,6 +16,13 @@ module CustomFields
16
16
  EOF
17
17
  end
18
18
 
19
+ def add_default_validation(klass)
20
+ # add validation if required field
21
+ if self.required?
22
+ klass.validates_presence_of self.safe_alias.to_sym
23
+ end
24
+ end
25
+
19
26
  end
20
27
 
21
28
  module ClassMethods
@@ -0,0 +1,114 @@
1
+ module CustomFields
2
+ module Types
3
+ module HasMany
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ field :target
9
+
10
+ validates_presence_of :target, :if => :has_many?
11
+
12
+ register_type :has_many, Array
13
+ end
14
+
15
+ module InstanceMethods
16
+
17
+ def apply_has_many_type(klass)
18
+ klass.class_eval <<-EOF
19
+
20
+ before_validation :store_#{self.safe_alias.singularize}_ids
21
+
22
+ def #{self.safe_alias}=(ids_or_objects)
23
+ if @_#{self._name}.nil?
24
+ @_#{self._name} = ProxyCollection.new('#{self.target.to_s}'.constantize, ids_or_objects)
25
+ else
26
+ @_#{self._name}.update(ids_or_objects)
27
+ end
28
+ end
29
+
30
+ def #{self.safe_alias}
31
+ @_#{self._name} ||= ProxyCollection.new('#{self.target.to_s}'.constantize, read_attribute(:#{self._name}))
32
+ end
33
+
34
+ def #{self.safe_alias.singularize}_ids
35
+ self.#{self.safe_alias}.ids
36
+ end
37
+
38
+ def store_#{self.safe_alias.singularize}_ids
39
+ write_attribute(:#{self._name}, #{self.safe_alias.singularize}_ids)
40
+ end
41
+ EOF
42
+ end
43
+
44
+ def add_has_many_validation(klass)
45
+ if self.required?
46
+ klass.validates_length_of self.safe_alias.to_sym, :minimum => 1, :too_short => :blank
47
+ end
48
+ end
49
+
50
+ end
51
+
52
+ class ProxyCollection
53
+
54
+ attr_accessor :target_klass, :ids, :values
55
+
56
+ def initialize(target_klass, array = [])
57
+ self.target_klass = target_klass
58
+ self.update(array || [])
59
+ end
60
+
61
+ def find(id)
62
+ id = BSON::ObjectId(id) unless id.is_a?(BSON::ObjectId)
63
+ self.values.detect { |obj_id| obj_id == id }
64
+ end
65
+
66
+ def update(values)
67
+ values = [] if values.blank?
68
+
69
+ self.ids = values.collect { |obj| self.id_for_sure(obj) }
70
+ self.values = values.collect { |obj| self.object_for_sure(obj) }
71
+ end
72
+
73
+ def <<(*args)
74
+ args.flatten.compact.each do |obj|
75
+ self.ids << self.id_for_sure(obj)
76
+ self.values << self.object_for_sure(obj)
77
+ end
78
+ end
79
+
80
+ alias :push :<<
81
+
82
+ def size
83
+ self.ids.size
84
+ end
85
+
86
+ alias :length :size
87
+
88
+ def method_missing(name, *args, &block)
89
+ self.values.send(name, *args, &block)
90
+ end
91
+
92
+ protected
93
+
94
+ def id_for_sure(id_or_object)
95
+ id_or_object.respond_to?(:_id) ? id_or_object._id : id_or_object
96
+ end
97
+
98
+ def object_for_sure(id_or_object)
99
+ if id_or_object.respond_to?(:_id)
100
+ id_or_object
101
+ else
102
+ if self.target_klass.embedded?
103
+ self.target_klass._parent.send(self.target_klass.association_name).find(id_or_object)
104
+ else
105
+ self.target_klass.find(id_or_object)
106
+ end
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,55 @@
1
+ module CustomFields
2
+ module Types
3
+ module HasOne
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ field :target
9
+
10
+ validates_presence_of :target, :if => :has_one?
11
+
12
+ register_type :has_one, BSON::ObjectId
13
+ end
14
+
15
+ module InstanceMethods
16
+
17
+ def apply_has_one_type(klass)
18
+ klass.class_eval <<-EOF
19
+
20
+ def #{self.safe_alias}=(id_or_object)
21
+ if id_or_object.respond_to?(:_id)
22
+ target_id = id_or_object._id
23
+ @_#{self._name} = id_or_object
24
+ else
25
+ target_id = id_or_object
26
+ @_#{self._name} = nil # empty previous cached value
27
+ end
28
+
29
+ write_attribute(:#{self._name}, target_id)
30
+ end
31
+
32
+ def #{self.safe_alias}
33
+ return @_#{self._name} unless @_#{self._name}.blank? # memoization
34
+
35
+ target_id = read_attribute(:#{self._name})
36
+
37
+ return nil if target_id.blank?
38
+
39
+ target_klass = '#{self.target.to_s}'.constantize
40
+
41
+ if target_klass.embedded?
42
+ @_#{self._name} = target_klass._parent.send(target_klass.association_name).find(target_id)
43
+ else
44
+ @_#{self._name} = target_klass.find(target_id)
45
+ end
46
+
47
+ @_#{self._name}
48
+ end
49
+ EOF
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,5 +1,5 @@
1
1
  module Mongoid
2
2
  module CustomFields
3
- VERSION = "1.0.0.beta.11"
3
+ VERSION = "1.0.0.beta.12"
4
4
  end
5
5
  end
data/lib/custom_fields.rb CHANGED
@@ -13,6 +13,8 @@ require 'custom_fields/types/category'
13
13
  require 'custom_fields/types/boolean'
14
14
  require 'custom_fields/types/date'
15
15
  require 'custom_fields/types/file'
16
+ require 'custom_fields/types/has_one'
17
+ require 'custom_fields/types/has_many'
16
18
  require 'custom_fields/proxy_class_enabler'
17
19
  require 'custom_fields/field'
18
20
  require 'custom_fields/metadata'
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: custom_fields
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196373
4
+ hash: 62196379
5
5
  prerelease: 6
6
6
  segments:
7
7
  - 1
8
8
  - 0
9
9
  - 0
10
10
  - beta
11
- - 11
12
- version: 1.0.0.beta.11
11
+ - 12
12
+ version: 1.0.0.beta.12
13
13
  platform: ruby
14
14
  authors:
15
15
  - Didier Lafforgue
@@ -17,12 +17,13 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2011-05-16 00:00:00 +02:00
20
+ date: 2011-05-20 00:00:00 +02:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
24
+ name: mongoid
24
25
  prerelease: false
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ requirement: &id001 !ruby/object:Gem::Requirement
26
27
  none: false
27
28
  requirements:
28
29
  - - ~>
@@ -34,11 +35,11 @@ dependencies:
34
35
  - 1
35
36
  version: 2.0.1
36
37
  type: :runtime
37
- requirement: *id001
38
- name: mongoid
38
+ version_requirements: *id001
39
39
  - !ruby/object:Gem::Dependency
40
+ name: activesupport
40
41
  prerelease: false
41
- version_requirements: &id002 !ruby/object:Gem::Requirement
42
+ requirement: &id002 !ruby/object:Gem::Requirement
42
43
  none: false
43
44
  requirements:
44
45
  - - ">="
@@ -50,11 +51,11 @@ dependencies:
50
51
  - 7
51
52
  version: 3.0.7
52
53
  type: :runtime
53
- requirement: *id002
54
- name: activesupport
54
+ version_requirements: *id002
55
55
  - !ruby/object:Gem::Dependency
56
+ name: locomotive_carrierwave
56
57
  prerelease: false
57
- version_requirements: &id003 !ruby/object:Gem::Requirement
58
+ requirement: &id003 !ruby/object:Gem::Requirement
58
59
  none: false
59
60
  requirements:
60
61
  - - ">="
@@ -64,8 +65,7 @@ dependencies:
64
65
  - 0
65
66
  version: "0"
66
67
  type: :runtime
67
- requirement: *id003
68
- name: locomotive_carrierwave
68
+ version_requirements: *id003
69
69
  description: Manage custom fields to a mongoid document or a collection. This module is one of the core features we implemented in our custom cms named Locomotive.
70
70
  email:
71
71
  - didier@nocoffee.fr
@@ -91,6 +91,8 @@ files:
91
91
  - lib/custom_fields/types/date.rb
92
92
  - lib/custom_fields/types/default.rb
93
93
  - lib/custom_fields/types/file.rb
94
+ - lib/custom_fields/types/has_many.rb
95
+ - lib/custom_fields/types/has_one.rb
94
96
  - lib/custom_fields/types/string.rb
95
97
  - lib/custom_fields/types/text.rb
96
98
  - lib/custom_fields/version.rb