document_form 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -1,4 +1,5 @@
1
- Copyright (c) 2010 [name of plugin creator]
1
+ Copyright (c) 2007-2008 Justin French
2
+ Copyright (c) 2010 Maurizio Casimirri
2
3
 
3
4
  Permission is hereby granted, free of charge, to any person obtaining
4
5
  a copy of this software and associated documentation files (the
@@ -18,3 +19,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
19
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
20
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
21
  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
data/Manifest CHANGED
@@ -1,9 +1,7 @@
1
1
  MIT-LICENSE
2
- README
2
+ README.textile
3
3
  Rakefile
4
4
  init.rb
5
5
  lib/document_form.rb
6
6
  lib/document_form/i18n.rb
7
- lib/mongo_mapper/plugins/multi_parameter_attributes.rb
8
- lib/mongoid/multi_parameter_attributes.rb
9
7
  Manifest
data/README.textile ADDED
@@ -0,0 +1,94 @@
1
+ h1. DocumentForm a Form Builder for Mongoid
2
+
3
+ DocumentForm is a Rails3 FormBuilder DSL that aims to provide a super fast and simple form-building tool to edit Mongoid documents in Rails3.
4
+ DocumentForm is a fork of <a href="http://github.com/justinfrench/formtastic">formtastic</a>.
5
+
6
+ h2. Basic Usage
7
+
8
+ DocumentForm allows you to create a form almost without coding.
9
+
10
+ Model
11
+
12
+ <pre>
13
+ class Person
14
+ include Mongoid::Document
15
+ include Mongoid::MultiParameterAttributes
16
+
17
+ validates_presence_of :name
18
+
19
+ field :name
20
+ field :secret, :private => true
21
+ field :birthday, :type => Date
22
+ field :department_number, :type => Integer, :range => 1..10
23
+
24
+ field :description, :long => true
25
+ end
26
+ </pre>
27
+
28
+ View
29
+
30
+ <pre>
31
+ <% document_form_for @object do |f| %>
32
+ <%= f.inputs %>
33
+ <%= f.buttons %>
34
+ <% end %>
35
+ </pre>
36
+
37
+ * Fields are rendered in the declaration order.
38
+ * Fields that has :private => true option are not rendered.
39
+
40
+ h2. File upload support
41
+
42
+ DocumentForm will render automatically file inputs for:
43
+
44
+ * Carrierwave
45
+ * Paperclip
46
+ * Any other upload library that generates a @_filename@ field in your model
47
+
48
+ DocumentForm will configure automatically your form with @:multipart => true@ for each models that has at least a @_filename@ field.
49
+
50
+ h2. Installation
51
+
52
+ Put this in your @Gemfile@
53
+
54
+ <pre>
55
+ gem document_form
56
+ </pre>
57
+
58
+ and run:
59
+
60
+ <pre>
61
+ bundle install
62
+ </pre>
63
+
64
+ h2. Some advanced examples
65
+
66
+ Belongs_to association
67
+
68
+ <pre>
69
+ class Person
70
+ include Mongoid::Document
71
+
72
+ referenced_in :department
73
+ end
74
+ </pre>
75
+
76
+ Will render a drop down list of departments
77
+
78
+
79
+ Has many association
80
+
81
+ <pre>
82
+ class Person
83
+ include Mongoid::Document
84
+
85
+ references_many :departments, :stored_as => :array
86
+ end
87
+ </pre>
88
+
89
+ Will render a sequence of checkboxes to pick multiple departments
90
+
91
+ h2. Other usage details
92
+
93
+ Please refer to <a href="http://github.com/justinfrench/formtastic">formtastic documentation</a> for a more detailed usage guide until DocumentForm documentation will be available.
94
+
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('document_form', '0.1.0') do |p|
5
+ Echoe.new('document_form', '0.1.2') do |p|
6
6
  p.description = "Form Builder for Rails3 and MongoID or MongoMapper"
7
7
  p.url = "http://github.com/mcasimir/document_form"
8
8
  p.author = "Maurizio Casimirri"
@@ -2,24 +2,23 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{document_form}
5
- s.version = "0.1.0"
5
+ s.version = "0.1.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
- s.authors = ["Maurizio Casimirri"]
9
- s.date = %q{2010-09-05}
8
+ s.authors = [%q{Maurizio Casimirri}]
9
+ s.date = %q{2011-12-04}
10
10
  s.description = %q{Form Builder for Rails3 and MongoID or MongoMapper}
11
11
  s.email = %q{maurizio.cas@gmail.com}
12
- s.extra_rdoc_files = ["README", "lib/document_form.rb", "lib/document_form/i18n.rb", "lib/mongo_mapper/plugins/multi_parameter_attributes.rb", "lib/mongoid/multi_parameter_attributes.rb"]
13
- s.files = ["MIT-LICENSE", "README", "Rakefile", "init.rb", "lib/document_form.rb", "lib/document_form/i18n.rb", "lib/mongo_mapper/plugins/multi_parameter_attributes.rb", "lib/mongoid/multi_parameter_attributes.rb", "Manifest", "document_form.gemspec"]
12
+ s.extra_rdoc_files = [%q{README.textile}, %q{lib/document_form.rb}, %q{lib/document_form/i18n.rb}]
13
+ s.files = [%q{MIT-LICENSE}, %q{README.textile}, %q{Rakefile}, %q{init.rb}, %q{lib/document_form.rb}, %q{lib/document_form/i18n.rb}, %q{Manifest}, %q{document_form.gemspec}]
14
14
  s.homepage = %q{http://github.com/mcasimir/document_form}
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Document_form", "--main", "README"]
16
- s.require_paths = ["lib"]
15
+ s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Document_form}, %q{--main}, %q{README.textile}]
16
+ s.require_paths = [%q{lib}]
17
17
  s.rubyforge_project = %q{document_form}
18
- s.rubygems_version = %q{1.3.7}
18
+ s.rubygems_version = %q{1.8.5}
19
19
  s.summary = %q{Form Builder for Rails3 and MongoID or MongoMapper}
20
20
 
21
21
  if s.respond_to? :specification_version then
22
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
22
  s.specification_version = 3
24
23
 
25
24
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
data/lib/document_form.rb CHANGED
@@ -20,12 +20,15 @@ if defined? Mongoid
20
20
  access = name.to_s
21
21
 
22
22
  @field_list << access
23
- set_field(access, options)
23
+ check_field_name!(name)
24
+ add_field(access, options)
24
25
  attr_protected name if options[:accessible] == false
25
26
  end
26
27
  end
27
28
  end
28
29
  end
30
+
31
+
29
32
  end
30
33
 
31
34
 
@@ -36,7 +39,7 @@ module DocumentForm #:nodoc:
36
39
  @@default_text_field_size = 60
37
40
  @@all_fields_required_by_default = false
38
41
  @@include_blank_for_select_by_default = true
39
- @@required_string = proc { (%{<abbr title="#{::DocumentForm::I18n.t(:required)}">*</abbr>}).html_safe }
42
+ @@required_string = "*" #proc { (%{<abbr title="#{::DocumentForm::I18n.t(:required)}">*</abbr>}).html_safe }
40
43
  @@optional_string = ''
41
44
  @@inline_errors = :sentence
42
45
  @@label_str_method = :humanize
@@ -51,7 +54,7 @@ module DocumentForm #:nodoc:
51
54
  :required_string, :optional_string, :inline_errors, :label_str_method, :collection_label_methods,
52
55
  :inline_order, :file_methods, :priority_countries, :i18n_lookups_by_default, :default_commit_button_accesskey
53
56
 
54
- RESERVED_COLUMNS = [:_id, :created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
57
+ RESERVED_COLUMNS = [:_id, :_type, :created_at, :updated_at, :created_on, :updated_on, :lock_version, :version]
55
58
 
56
59
  INLINE_ERROR_TYPES = [:sentence, :list, :first]
57
60
 
@@ -104,11 +107,25 @@ module DocumentForm #:nodoc:
104
107
  #
105
108
  def input(method, options = {})
106
109
 
110
+ if options[:class].present?
111
+ options[:input_html] ||= {}
112
+ options[:input_html][:class] = options[:class]
113
+ end
114
+
107
115
 
108
116
  options[:required] = method_required?(method) unless options.key?(:required)
109
117
  mm_key = mongomapper_key(method)
110
118
 
111
- return nil if !options[:as] && mm_key.type.nil?
119
+ if mm_key
120
+ return nil if !options[:as] && mm_key.type.nil?
121
+
122
+ if(!options[:as] && mm_key.options[:in].present?)
123
+ options[:as] = :select
124
+ options[:collection] = mm_key.options[:in]
125
+ end
126
+ end
127
+
128
+
112
129
  options[:as] ||= default_input_type(method, options)
113
130
 
114
131
  html_class = [ options[:as], (options[:required] ? :required : :optional) ]
@@ -289,6 +306,7 @@ module DocumentForm #:nodoc:
289
306
  inputs_for_nested_attributes(*(args << html_options), &block)
290
307
  elsif block_given?
291
308
  field_set_and_list_wrapping(*(args << html_options), &block)
309
+ return nil
292
310
  else
293
311
  if @object && args.empty?
294
312
  args = []
@@ -465,7 +483,7 @@ module DocumentForm #:nodoc:
465
483
  protected
466
484
 
467
485
  class FieldAdapter
468
- attr_accessor :name, :type, :required, :options
486
+ attr_accessor :name, :type, :required, :options, :association, :macro
469
487
  end
470
488
 
471
489
  class OrderedHashWithIndifferentAccess < ActiveSupport::OrderedHash
@@ -504,7 +522,8 @@ module DocumentForm #:nodoc:
504
522
  mmfl.delete("_id")
505
523
  mmfl
506
524
  when :mongoid
507
- resource_class.fields.stringify_keys
525
+ #raise resource_class.fields.stringify_keys.inspect
526
+ resource_class.fields.stringify_keys
508
527
  end || {}
509
528
 
510
529
  flds.keys.each do |name|
@@ -513,7 +532,7 @@ module DocumentForm #:nodoc:
513
532
  fa = FieldAdapter.new
514
533
  fa.name = name
515
534
  fa.options = field.options
516
- fa.type = field.type
535
+ fa.type = (name.to_s =~ /_id$/) ? BSON::ObjectId : field.type
517
536
  fa.required = is_required_field?(field)
518
537
 
519
538
  flds[name] = fa
@@ -527,6 +546,19 @@ module DocumentForm #:nodoc:
527
546
  f = unordered[fn]
528
547
  if f
529
548
  @df_resource_fields[fn] = f
549
+
550
+ elsif orm == :mongoid
551
+ f = resource_class.associations[fn]
552
+
553
+ if f && !f.options[:private]
554
+ fa = FieldAdapter.new
555
+ fa.name = fn
556
+ fa.options = f.options
557
+ fa.type = f.association
558
+ fa.required = is_required_field?(f)
559
+ @df_resource_fields[fn] = fa
560
+ end
561
+
530
562
  end
531
563
  }
532
564
 
@@ -618,7 +650,12 @@ module DocumentForm #:nodoc:
618
650
  # configuration option @@all_fields_required_by_default is used.
619
651
  #
620
652
  def method_required?(attribute) #:nodoc:
621
- resource_fields[attribute].required
653
+ rf = resource_fields[attribute]
654
+ if !rf.nil?
655
+ rf.required
656
+ else
657
+ false
658
+ end
622
659
  end
623
660
 
624
661
  # Determines whether the given options evaluate to true
@@ -657,13 +694,22 @@ module DocumentForm #:nodoc:
657
694
 
658
695
  # Outputs a label and standard Rails text field inside the wrapper.
659
696
  def numeric_input(method, options)
697
+ options ||= {}
698
+ html_options = options[:input_html] || {}
699
+
700
+ html_options[:size] ||= 8
701
+ options[:input_html] = html_options
702
+
660
703
  basic_input_helper(:text_field, :numeric, method, options)
661
704
  end
662
705
 
663
706
  # Ouputs a label and standard Rails text area inside the wrapper.
664
707
  def text_input(method, options)
665
708
  options[:input_html] ||= {}
666
- options[:input_html][:cols] ||= 60
709
+ options[:input_html][:cols] ||= options[:cols]
710
+ options[:input_html][:rows] ||= options[:rows]
711
+
712
+ #options[:input_html][:cols] ||= 60
667
713
  basic_input_helper(:text_area, :text, method, options)
668
714
  end
669
715
 
@@ -676,6 +722,7 @@ module DocumentForm #:nodoc:
676
722
  def markup_input(method, options)
677
723
  options[:input_html] ||= {}
678
724
  options[:input_html][:class] = "markup"
725
+ options[:input_html][:rows] ||= 20
679
726
  basic_input_helper(:text_area, :text, method, options)
680
727
  end
681
728
 
@@ -810,7 +857,10 @@ module DocumentForm #:nodoc:
810
857
  #
811
858
  def select_input(method, options)
812
859
  mm_key = mongomapper_key(method)
860
+ options[:include_blank] ||= mm_key.options[:allow_blank]
813
861
  options[:include_blank] = false if mm_key && mm_key.options[:required] && !options[:include_blank].present?
862
+ options[:collection] ||= mm_key.options[:in]
863
+ options[:collection] ||= mm_key.options[:collection]
814
864
 
815
865
  html_options = options.delete(:input_html) || {}
816
866
  options = set_include_blank(options)
@@ -974,10 +1024,10 @@ module DocumentForm #:nodoc:
974
1024
  )
975
1025
 
976
1026
  li_options = value_as_class ? { :class => [method.to_s.singularize, value.to_s.downcase].join('_') } : {}
977
- template.content_tag(:li, li_content, li_options)
1027
+ template.content_tag(:li, li_content.html_safe, li_options).html_safe
978
1028
  end
979
1029
 
980
- field_set_and_list_wrapping_for_method(method, options.merge(:label_for => input_ids.first), list_item_content)
1030
+ field_set_and_list_wrapping_for_method(method, options.merge(:label_for => input_ids.first), list_item_content).html_safe
981
1031
  end
982
1032
  alias :boolean_radio_input :radio_input
983
1033
 
@@ -1073,6 +1123,11 @@ module DocumentForm #:nodoc:
1073
1123
  # This is an absolute abomination, but so is the official Rails select_date().
1074
1124
  #
1075
1125
  def date_or_datetime_input(method, options)
1126
+
1127
+ field_options = resource_fields[method].options
1128
+ options ||= {}
1129
+ options[:start_year] ||= field_options[:start_year]
1130
+
1076
1131
  position = { :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6 }
1077
1132
  i18n_date_order = ::I18n.t(:order, :scope => [:date])
1078
1133
  i18n_date_order = nil unless i18n_date_order.is_a?(Array)
@@ -1086,8 +1141,11 @@ module DocumentForm #:nodoc:
1086
1141
 
1087
1142
  default_time = ::Time.now
1088
1143
 
1144
+ datetime_obj = @object.send(method) if @object
1145
+
1089
1146
  # Gets the datetime object. It can be a Fixnum, Date or Time, or nil.
1090
- datetime = options[:selected] || (@object ? @object.send(method) : default_time) || default_time
1147
+ datetime = options[:selected] || datetime_obj || default_time
1148
+ # datetime = datetime.in_time_zone(Time.zone) if (datetime && datetime.respond_to?(:in_time_zone))
1091
1149
 
1092
1150
  html_options = options.delete(:input_html) || {}
1093
1151
  input_ids = []
@@ -1227,29 +1285,31 @@ module DocumentForm #:nodoc:
1227
1285
  #
1228
1286
  #
1229
1287
  def array_input(method, options)
1230
- cls = self.model_name.constantize
1231
- assoc = cls.associations.find{|a| (!a.last.options[:in].nil?) && a.last.options[:in].to_sym == method && a.last.type == :many}
1232
- if assoc.present?
1233
- assoc_name = assoc.first
1234
- mm_assoc = assoc.last
1288
+ m = method.to_s
1289
+
1290
+ if (m =~ /_ids/) && (assoc = resource_class.associations[m.gsub(/_ids$/, "").pluralize]) && assoc.association == Mongoid::Associations::ReferencesManyAsArray
1291
+ f = resource_fields[m]
1292
+ klass = f.options[:inverse_class_name].constantize
1235
1293
 
1236
- collection = mm_assoc.name.to_s.camelize.singularize.constantize.all
1294
+ collection = klass.all
1237
1295
  checked = @object.send(:"#{method}") if @object
1238
1296
  checked ||= []
1239
1297
 
1240
1298
 
1241
1299
  checkboxes = collection.map { |elem|
1242
1300
  name = "#{self.model_name.tableize.singularize}[#{method.to_s}][]"
1243
- ckb = if checked.include? elem._id.to_s
1301
+ ckb = if checked.include? elem.id
1244
1302
  template.check_box_tag(name, elem._id, {}, :checked => "checked")
1245
1303
  else
1246
1304
  template.check_box_tag(name, elem._id)
1247
1305
  end
1248
- label = to_label(elem)
1306
+ label = format_object(elem)
1249
1307
  [ckb, label].join(" ")
1250
1308
  }.map{|checkbox| "<li>#{checkbox}</li>"}.join
1251
1309
 
1252
- field_set_and_list_wrapping_for_method(method, options, checkboxes)
1310
+ method = m.gsub(/_ids$/, "").pluralize.to_sym if !options[:label].present?
1311
+
1312
+ field_set_and_list_wrapping_for_method(method, options, checkboxes.html_safe)
1253
1313
  end
1254
1314
  end
1255
1315
  # Outputs a country select input, wrapping around a regular country_select helper.
@@ -1267,7 +1327,7 @@ module DocumentForm #:nodoc:
1267
1327
  # f.input :location, :as => :country, :priority_countries => /Australia/ # set your own
1268
1328
  #
1269
1329
  def country_input(method, options)
1270
- raise "To use the :country input, please install a country_select plugin, like this one: http://github.com/rails/iso-3166-country-select" unless self.respond_to?(:country_select)
1330
+ return basic_input_helper(:text_field, :string, method, options) unless self.respond_to?(:country_select)
1271
1331
 
1272
1332
  html_options = options.delete(:input_html) || {}
1273
1333
  priority_countries = options.delete(:priority_countries) || @@priority_countries
@@ -1451,8 +1511,8 @@ module DocumentForm #:nodoc:
1451
1511
  if column = resource_fields[method]
1452
1512
 
1453
1513
  # Special cases where the column type doesn't map to an input method.
1454
- type = column.type.name.underscore.to_sym
1455
-
1514
+ type = column.type.name.split("::").last.underscore.to_sym
1515
+ type = :string if type == :object
1456
1516
 
1457
1517
  case type
1458
1518
  when :string
@@ -1517,55 +1577,84 @@ module DocumentForm #:nodoc:
1517
1577
  end
1518
1578
  end
1519
1579
 
1520
-
1521
- def label_key(doc)
1522
- if doc.keys.has_key? :name
1523
- :name
1524
- elsif doc.keys.has_key? :title
1525
- :title
1526
- end
1527
- end
1528
-
1529
- def to_label(obj)
1530
- lcol = label_key(obj.class)
1531
- if obj.respond_to? :to_label
1532
- obj.to_label
1533
- elsif lcol
1534
- obj.send :"#{lcol}"
1535
- else
1536
- ""
1537
- end
1538
- end
1580
+ # def fields_method(doc)
1581
+ # if (defined? MongoMapper) && (doc.include? MongoMapper::Document)
1582
+ # :keys
1583
+ # elsif (defined? Mongoid) && (doc.include? Mongoid::Document)
1584
+ # :fields
1585
+ # end
1586
+ # end
1587
+
1588
+ # def label_key(doc)
1589
+ # if doc.send(fields_method(doc)).has_key? :name
1590
+ # :name
1591
+ # elsif doc.send(fields_method(doc)).has_key? :title
1592
+ # :title
1593
+ # end
1594
+ # end
1595
+
1596
+ # def to_label(obj)
1597
+ # lcol = label_key(obj.class)
1598
+ # if obj.respond_to? :to_label
1599
+ # obj.to_label
1600
+ # elsif lcol
1601
+ # obj.send :"#{lcol}"
1602
+ # else
1603
+ # ""
1604
+ # end
1605
+ # end
1539
1606
 
1540
1607
  def format_object(object)
1541
- if object.class.include? MongoMapper::Document
1542
- to_label(object)
1608
+ if object.respond_to? :to_label
1609
+ object.to_label
1543
1610
  elsif object.is_a? DateTime
1544
1611
  I18n.l(object)
1545
1612
  elsif object.is_a? Symbol
1546
1613
  t(object)
1614
+ elsif object.respond_to? :name
1615
+ object.name
1616
+ elsif object.respond_to? :title
1617
+ object.title
1547
1618
  else
1548
1619
  object
1549
1620
  end
1550
1621
  end
1551
1622
 
1552
1623
 
1624
+ def referenced_in_input(method, options)
1625
+
1626
+ field = resource_fields[method]
1627
+ association_class = field.name.to_s.singularize.camelize.constantize
1553
1628
 
1629
+ options[:collection] = association_class.all.map {|obj| [format_object(obj), obj.id]}
1630
+
1631
+ if field.options[:allow_blank] == false || field.options[:required] == true
1632
+ options[:include_blank] = false
1633
+ end
1634
+
1635
+ select_input(method, options)
1636
+ end
1554
1637
 
1555
1638
  def object_id_input(method, options)
1639
+ field = resource_fields[method]
1556
1640
 
1557
- cls = self.model_name.constantize
1558
- key = cls.keys[method]
1559
- assoc = cls.associations[method.to_s.gsub(/_id$/, "")]
1560
- association_class = assoc.name.to_s.singularize.camelize.constantize
1641
+ if options[:collection].nil?
1642
+ if options[:class_name].present?
1643
+ association_class = options[:class_name].camelize.constantize
1644
+ else
1645
+ association_class = field.name.to_s.gsub(/_id$/, "").singularize.camelize.constantize
1646
+ end
1647
+ options[:collection] = association_class.all.map {|obj| [format_object(obj), obj.id]}
1648
+ end
1561
1649
 
1562
- options[:collection] = association_class.all.map {|obj| [format_object(obj), obj.id]}
1563
1650
 
1564
- if key.options[:allow_blank] == false || key.options[:required] == true
1651
+ if field.options[:allow_blank] == false || field.options[:required] == true
1565
1652
  options[:include_blank] = false
1566
1653
  end
1567
1654
 
1568
1655
  select_input(method, options)
1656
+
1657
+
1569
1658
  end
1570
1659
 
1571
1660
  # Used by select and radio inputs. The collection can be retrieved by
@@ -1911,6 +2000,8 @@ module DocumentForm #:nodoc:
1911
2000
  options[:html][:class] = class_names.join(" ")
1912
2001
 
1913
2002
  doctype = class_names.last.camelize.constantize
2003
+
2004
+
1914
2005
  has_attachments = false
1915
2006
  rfields = if doctype.respond_to?("fields")
1916
2007
  doctype.fields
metadata CHANGED
@@ -1,12 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: document_form
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 0
9
- version: 0.1.0
4
+ prerelease:
5
+ version: 0.1.2
10
6
  platform: ruby
11
7
  authors:
12
8
  - Maurizio Casimirri
@@ -14,8 +10,7 @@ autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
12
 
17
- date: 2010-09-05 00:00:00 +02:00
18
- default_executable:
13
+ date: 2011-12-04 00:00:00 Z
19
14
  dependencies: []
20
15
 
21
16
  description: Form Builder for Rails3 and MongoID or MongoMapper
@@ -25,23 +20,18 @@ executables: []
25
20
  extensions: []
26
21
 
27
22
  extra_rdoc_files:
28
- - README
23
+ - README.textile
29
24
  - lib/document_form.rb
30
25
  - lib/document_form/i18n.rb
31
- - lib/mongo_mapper/plugins/multi_parameter_attributes.rb
32
- - lib/mongoid/multi_parameter_attributes.rb
33
26
  files:
34
27
  - MIT-LICENSE
35
- - README
28
+ - README.textile
36
29
  - Rakefile
37
30
  - init.rb
38
31
  - lib/document_form.rb
39
32
  - lib/document_form/i18n.rb
40
- - lib/mongo_mapper/plugins/multi_parameter_attributes.rb
41
- - lib/mongoid/multi_parameter_attributes.rb
42
33
  - Manifest
43
34
  - document_form.gemspec
44
- has_rdoc: true
45
35
  homepage: http://github.com/mcasimir/document_form
46
36
  licenses: []
47
37
 
@@ -52,7 +42,7 @@ rdoc_options:
52
42
  - --title
53
43
  - Document_form
54
44
  - --main
55
- - README
45
+ - README.textile
56
46
  require_paths:
57
47
  - lib
58
48
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -60,22 +50,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
60
50
  requirements:
61
51
  - - ">="
62
52
  - !ruby/object:Gem::Version
63
- segments:
64
- - 0
65
53
  version: "0"
66
54
  required_rubygems_version: !ruby/object:Gem::Requirement
67
55
  none: false
68
56
  requirements:
69
57
  - - ">="
70
58
  - !ruby/object:Gem::Version
71
- segments:
72
- - 1
73
- - 2
74
59
  version: "1.2"
75
60
  requirements: []
76
61
 
77
62
  rubyforge_project: document_form
78
- rubygems_version: 1.3.7
63
+ rubygems_version: 1.8.5
79
64
  signing_key:
80
65
  specification_version: 3
81
66
  summary: Form Builder for Rails3 and MongoID or MongoMapper
data/README DELETED
@@ -1,13 +0,0 @@
1
- DocumentForm
2
- ============
3
-
4
- Introduction goes here.
5
-
6
-
7
- Example
8
- =======
9
-
10
- Example goes here.
11
-
12
-
13
- Copyright (c) 2010 [name of plugin creator], released under the MIT license
@@ -1,98 +0,0 @@
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
-
@@ -1,95 +0,0 @@
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
-