document_form 0.1.0
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.
- data/MIT-LICENSE +20 -0
- data/Manifest +9 -0
- data/README +13 -0
- data/Rakefile +15 -0
- data/document_form.gemspec +30 -0
- data/init.rb +4 -0
- data/lib/document_form.rb +1938 -0
- data/lib/document_form/i18n.rb +33 -0
- data/lib/mongo_mapper/plugins/multi_parameter_attributes.rb +98 -0
- data/lib/mongoid/multi_parameter_attributes.rb +95 -0
- metadata +83 -0
@@ -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
|
+
|