document_form 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ module DocumentForm
2
+ module I18n
3
+
4
+ DEFAULT_SCOPE = [:document_form].freeze
5
+ DEFAULT_VALUES = {
6
+ :required => 'required',
7
+ :yes => 'Yes',
8
+ :no => 'No',
9
+ :create => 'Create {{model}}',
10
+ :update => 'Update {{model}}'
11
+ }.freeze
12
+ SCOPES = [
13
+ '{{model}}.{{action}}.{{attribute}}',
14
+ '{{model}}.{{attribute}}',
15
+ '{{attribute}}'
16
+ ]
17
+
18
+ class << self
19
+
20
+ def translate(*args)
21
+ key = args.shift.to_sym
22
+ options = args.extract_options!
23
+ options.reverse_merge!(:default => DEFAULT_VALUES[key])
24
+ options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
25
+ ::I18n.translate(key, *(args << options))
26
+ end
27
+ alias :t :translate
28
+
29
+ end
30
+
31
+ end
32
+ end
33
+
@@ -0,0 +1,98 @@
1
+ if defined? MongoMapper
2
+
3
+ module MongoMapper
4
+ module Plugins
5
+ module MultiParameterAttributes
6
+ def self.included(model)
7
+ model.plugin self
8
+ end
9
+
10
+ module InstanceMethods
11
+ def attributes=(new_attributes)
12
+ return if new_attributes.nil?
13
+
14
+ multi_parameter_attributes = []
15
+ normal_attributes = {}
16
+
17
+ new_attributes.each do |k, v|
18
+ if k.to_s.include?("(")
19
+ multi_parameter_attributes << [ k.to_s, v ]
20
+ else
21
+ normal_attributes[k] = v
22
+ end
23
+ end
24
+
25
+ assign_multiparameter_attributes(multi_parameter_attributes)
26
+
27
+ super(normal_attributes)
28
+ end
29
+
30
+ # Instantiates objects for all attribute classes that needs more than one constructor parameter. This is done
31
+ # by calling new on the column type or aggregation type (through composed_of) object with these parameters.
32
+ # So having the pairs written_on(1) = "2004", written_on(2) = "6", written_on(3) = "24", will instantiate
33
+ # written_on (a date type) with Date.new("2004", "6", "24"). You can also specify a typecast character in the
34
+ # parentheses to have the parameters typecasted before they're used in the constructor. Use i for Fixnum, f for Float,
35
+ # s for String, and a for Array. If all the values for a given attribute are empty, the attribute will be set to nil.
36
+ def assign_multiparameter_attributes(pairs)
37
+ execute_callstack_for_multiparameter_attributes(
38
+ extract_callstack_for_multiparameter_attributes(pairs)
39
+ )
40
+ end
41
+
42
+ def execute_callstack_for_multiparameter_attributes(callstack)
43
+ callstack.each do |name, values_with_empty_parameters|
44
+ # in order to allow a date to be set without a year, we must keep the empty values.
45
+ # Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
46
+ values = values_with_empty_parameters.reject(&:nil?)
47
+
48
+ if !values.reject{|x| x.blank? }.empty?
49
+ key = self.class.keys[name]
50
+ raise ArgumentError, "Unknown key #{name}" if key.nil?
51
+ klass = key.type
52
+
53
+ value = if Time == klass
54
+ Time.zone.local(*values.map(&:to_i))
55
+ elsif Date == klass
56
+ begin
57
+ values = values_with_empty_parameters.map{|v| v.blank? ? 1 : v.to_i}
58
+ Date.new(*values)
59
+ rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
60
+ Time.zone.local(*values.map(&:to_i)).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
61
+ end
62
+ else
63
+ klass.new(*values)
64
+ end
65
+ writer_method = "#{name}="
66
+ if respond_to?(writer_method)
67
+ self.send(writer_method, value)
68
+ else
69
+ self[name.to_s] = value
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ def extract_callstack_for_multiparameter_attributes(pairs)
76
+ attributes = { }
77
+
78
+ for pair in pairs
79
+ multiparameter_name, value = pair
80
+ attribute_name = multiparameter_name.split("(").first
81
+ attributes[attribute_name] = [] unless attributes.include?(attribute_name)
82
+
83
+ attributes[attribute_name] << [ find_parameter_position(multiparameter_name), value ]
84
+ end
85
+
86
+ attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
87
+ end
88
+
89
+ def find_parameter_position(multiparameter_name)
90
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ end
98
+
@@ -0,0 +1,95 @@
1
+ module Mongoid
2
+ module MultiParameterAttributes
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ self.before_validation :handle_multiparameter_attributes
7
+ end
8
+
9
+ module InstanceMethods
10
+ protected
11
+
12
+ def handle_multiparameter_attributes
13
+ multiparameter_attributes = []
14
+ self.attributes.each_pair do |attr_name, value|
15
+ multiparameter_attributes << [attr_name, value] if attr_name.include?("(")
16
+ end
17
+
18
+ assign_multiparameter_attributes(multiparameter_attributes) if multiparameter_attributes.any?
19
+ end
20
+
21
+ def assign_multiparameter_attributes(pairs)
22
+ execute_callstack_for_multiparameter_attributes(
23
+ extract_callstack_for_multiparameter_attributes(pairs)
24
+ )
25
+ end
26
+
27
+ def execute_callstack_for_multiparameter_attributes(callstack)
28
+ errors = []
29
+ callstack.each do |name, values_with_empty_parameters|
30
+ begin
31
+ klass = self.class.fields[name].type
32
+
33
+ puts "Class is #{klass.to_s}"
34
+ # in order to allow a date to be set without a year, we must keep the empty values.
35
+ # Otherwise, we wouldn't be able to distinguish it from a date with an empty day.
36
+ values = values_with_empty_parameters.reject(&:nil?)
37
+
38
+ if values.empty?
39
+ send(name + "=", nil)
40
+ else
41
+
42
+ value = if Time == klass
43
+ instantiate_time_object(name, values)
44
+ elsif Date == klass
45
+ begin
46
+ values = values_with_empty_parameters.collect do |v| v.nil? ? 1 : v end
47
+ Date.new(*values)
48
+ rescue ArgumentError => ex # if Date.new raises an exception on an invalid date
49
+ instantiate_time_object(name, values).to_date # we instantiate Time object and convert it back to a date thus using Time's logic in handling invalid dates
50
+ end
51
+ else
52
+ klass.new(*values)
53
+ end
54
+
55
+ send(name + "=", value)
56
+ end
57
+ rescue => ex
58
+ errors << AttributeAssignmentError.new("error on assignment #{values.inspect} to #{name}", ex, name)
59
+ end
60
+ end
61
+ unless errors.empty?
62
+ raise MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
63
+ end
64
+ end
65
+
66
+ def extract_callstack_for_multiparameter_attributes(pairs)
67
+ attributes = { }
68
+
69
+ for pair in pairs
70
+ multiparameter_name, value = pair
71
+ attribute_name = multiparameter_name.split("(").first
72
+ attributes[attribute_name] = [] unless attributes.include?(attribute_name)
73
+
74
+ parameter_value = value.empty? ? nil : type_cast_attribute_value(multiparameter_name, value)
75
+ attributes[attribute_name] << [ find_parameter_position(multiparameter_name), parameter_value ]
76
+ end
77
+
78
+ attributes.each { |name, values| attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last } }
79
+ end
80
+
81
+ def type_cast_attribute_value(multiparameter_name, value)
82
+ multiparameter_name =~ /\([0-9]*([if])\)/ ? value.send("to_" + $1) : value
83
+ end
84
+
85
+ def find_parameter_position(multiparameter_name)
86
+ multiparameter_name.scan(/\(([0-9]*).*\)/).first.first
87
+ end
88
+
89
+ def instantiate_time_object(name, values)
90
+ Time.zone.local(*values)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: document_form
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Maurizio Casimirri
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-05 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Form Builder for Rails3 and MongoID or MongoMapper
22
+ email: maurizio.cas@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - README
29
+ - lib/document_form.rb
30
+ - lib/document_form/i18n.rb
31
+ - lib/mongo_mapper/plugins/multi_parameter_attributes.rb
32
+ - lib/mongoid/multi_parameter_attributes.rb
33
+ files:
34
+ - MIT-LICENSE
35
+ - README
36
+ - Rakefile
37
+ - init.rb
38
+ - lib/document_form.rb
39
+ - lib/document_form/i18n.rb
40
+ - lib/mongo_mapper/plugins/multi_parameter_attributes.rb
41
+ - lib/mongoid/multi_parameter_attributes.rb
42
+ - Manifest
43
+ - document_form.gemspec
44
+ has_rdoc: true
45
+ homepage: http://github.com/mcasimir/document_form
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --line-numbers
51
+ - --inline-source
52
+ - --title
53
+ - Document_form
54
+ - --main
55
+ - README
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ none: false
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ segments:
72
+ - 1
73
+ - 2
74
+ version: "1.2"
75
+ requirements: []
76
+
77
+ rubyforge_project: document_form
78
+ rubygems_version: 1.3.7
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Form Builder for Rails3 and MongoID or MongoMapper
82
+ test_files: []
83
+