formgen 0.1.0 → 0.2.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.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2011 Charlie
1
+ Copyright (c) 2011 Pullmonkey
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -1,23 +1,29 @@
1
1
  = formgen
2
2
 
3
- rails g skizmo:form --help
3
+ rails g skizmo:form --help
4
+
4
5
  === Usage:
5
6
  rails generate skizmo:form NAME [options]
6
7
 
7
8
  === Options:
8
- [--javascript] # Indicates when to generate javascript
9
- # Default: true
10
- [--helpers] # Indicates when to generate helpers
11
- # Default: true
9
+ [--helpers] # Indicates when to generate helpers
10
+ # Default: true
11
+ [--javascript] # Indicates when to generate javascript
12
+ # Default: true
13
+ [--select-boxes] # Indicates when to generate select boxes
14
+ # Default: true
12
15
 
13
16
  === Runtime options:
14
- -p, [--pretend] # Run but do not make any changes
17
+ -f, [--force] # Overwrite files that already exist
15
18
  -s, [--skip] # Skip files that already exist
16
19
  -q, [--quiet] # Supress status output
17
- -f, [--force] # Overwrite files that already exist
20
+ -p, [--pretend] # Run but do not make any changes
18
21
 
19
22
  === Description:
20
- Generates a form per usual but with fields_for for the has_many and belongs_to associations.
23
+ Generates a form per usual but with fields_for for the has_many and belongs_to associations that are
24
+ "accepted_nested_attributes". If the fields are not accepted nested attributes, then they are
25
+ selectable options, multi-select for has_many and single select for belongs_to. 'has_attached_file'
26
+ will trigger the file_field input and create a multipart form.
21
27
 
22
28
  === Example:
23
29
  rails generate skizmo:form Foo
@@ -29,11 +35,14 @@ rails g skizmo:form --help
29
35
 
30
36
  accepts_nested_attributes_for :bars
31
37
  accepts_nested_attributes_for :baz
38
+
39
+ has_attached_file :image
32
40
  end
33
41
 
34
42
  This will create:
35
43
  public/javascripts/jquery.add_remove_links.js
36
44
  app/helpers/add_remove_links_helper.rb
45
+ app/helpers/foo_setup_helper.rb
37
46
  app/views/foos/new.html.erb
38
47
  app/views/foos/edit.html.erb
39
48
  app/views/foos/_form.html.erb
@@ -41,6 +50,15 @@ rails g skizmo:form --help
41
50
  app/views/foos/_baz_fields.html.erb
42
51
 
43
52
 
53
+ == FAQ
54
+
55
+ * I'm getting this error:
56
+
57
+ undefined method `setup_something' for #<#<Class:
58
+
59
+ Make sure the generated helper is being loaded - restart your rails server.
60
+
61
+
44
62
  == Contributing to formgen
45
63
 
46
64
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -5,16 +5,15 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{formgen}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pullmonkey"]
12
- s.date = %q{2011-11-15}
12
+ s.date = %q{2011-11-16}
13
13
  s.description = %q{Ruby on Rails form generator based on has_many and belongs_to associations. Includes the helpers and javascript for adding and removing fields_for form attributes.}
14
14
  s.email = %q{info@skizmo.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
- "README",
18
17
  "README.rdoc"
19
18
  ]
20
19
  s.files = [
@@ -22,7 +21,6 @@ Gem::Specification.new do |s|
22
21
  "Gemfile",
23
22
  "Gemfile.lock",
24
23
  "LICENSE.txt",
25
- "README",
26
24
  "README.rdoc",
27
25
  "Rakefile",
28
26
  "VERSION",
@@ -36,6 +34,7 @@ Gem::Specification.new do |s|
36
34
  "lib/generators/skizmo/form/templates/helper.rb",
37
35
  "lib/generators/skizmo/form/templates/javascript.js",
38
36
  "lib/generators/skizmo/form/templates/new.html.erb",
37
+ "lib/generators/skizmo/form/templates/setup_helper.rb",
39
38
  "test/helper.rb",
40
39
  "test/test_formgen.rb"
41
40
  ]
@@ -1,5 +1,5 @@
1
1
  Description:
2
- Generates a form per usual but with fields_for for the has_many and belongs_to associations.
2
+ Generates a form per usual but with fields_for for the has_many and belongs_to associations that are "accepted_nested_attributes". If the fields are not accepted nested attributes, then they are selectable options, multi-select for has_many and single select for belongs_to. 'has_attached_file' will trigger the file_field input and create a multipart form.
3
3
 
4
4
  Example:
5
5
  rails generate skizmo:form Foo
@@ -11,11 +11,14 @@ Example:
11
11
 
12
12
  accepts_nested_attributes_for :bars
13
13
  accepts_nested_attributes_for :baz
14
+
15
+ has_attached_file :image
14
16
  end
15
17
 
16
18
  This will create:
17
19
  public/javascripts/jquery.add_remove_links.js
18
20
  app/helpers/add_remove_links_helper.rb
21
+ app/helpers/foo_setup_helper.rb
19
22
  app/views/foos/new.html.erb
20
23
  app/views/foos/edit.html.erb
21
24
  app/views/foos/_form.html.erb
@@ -6,15 +6,21 @@ module Skizmo
6
6
  class_option :javascript, :type => :boolean, :default => true,
7
7
  :description => "Include javascript to add and remove associated attributes if there are has_many associations"
8
8
  class_option :helpers, :type => :boolean, :default => true,
9
- :description => "Update helpers to add link_to_add and link_to_remove methods if there are has_many associations"
9
+ :description => "Update helpers to add link_to_add and link_to_remove methods if there are has_many associations, as well as a setup method for building objects required for nested attribute associations and for building selectable lists for select boxes"
10
+ class_option :select_boxes, :type => :boolean, :default => true,
11
+ :description => "Generates select box selections for belongs_to and has_many associations that are not accepted as nested_attributes"
10
12
 
11
13
  def generate_form
12
14
  unless nested_has_many_classes.empty?
13
15
  copy_file "javascript.js", "public/javascripts/jquery.add_remove_links.js" if options.javascript?
14
16
  copy_file "helper.rb", "app/helpers/add_remove_links_helper.rb" if options.helpers?
15
17
  end
18
+ unless nested_classes_with_attributes.empty?
19
+ template "setup_helper.rb", "app/helpers/#{file_name}_setup_helper.rb" if options.helpers?
20
+ end
16
21
  template "new.html.erb", "app/views/#{file_name.pluralize}/new.html.erb"
17
22
  template "edit.html.erb", "app/views/#{file_name.pluralize}/edit.html.erb"
23
+ @have_attachment_string = have_attachments? ? ", :html => { :multipart => true }" : ""
18
24
  template "_form.html.erb", "app/views/#{file_name.pluralize}/_form.html.erb"
19
25
  nested_classes_with_attributes.each do |hash_with_kls_and_attrs|
20
26
  @kls = hash_with_kls_and_attrs[:kls] # class object
@@ -28,22 +34,40 @@ module Skizmo
28
34
  private
29
35
 
30
36
  def file_name
31
- name.underscore
37
+ cls_underscore
32
38
  end
33
39
 
34
40
  def cls
35
- name.classify.constantize
41
+ cls_classname.constantize
36
42
  end
37
43
 
44
+ def cls_classname
45
+ name.classify.to_s
46
+ end
47
+
48
+ def cls_underscore
49
+ name.to_s.underscore
50
+ end
51
+
52
+ # Base this on has_attached_file
38
53
  def attributes_worth_using_in_the_form(options={})
39
54
  kls = options[:class] || cls
40
55
  rejects = ["created_at","updated_at","created_on","updated_on","id",/_id$/]
41
- kls.column_names.reject do |x|
42
- rejects.include?(x) || !rejects.select{|y| y.is_a?(Regexp) and x =~ y}.empty?
56
+ # consolidate x_file_name, x_content_type and x_file_size to just x
57
+ attachment_endings = ["_file_name", "_content_type", "_file_size", "_updated_at"]
58
+ attachments = attachments_for(kls) || []
59
+ attachment_rejects = attachment_endings.map{|x| attachments.map{|y| y.to_s + x.to_s}}.flatten.uniq
60
+ attrs_for_form = kls.column_names.reject do |x|
61
+ rejects.include?(x) || !rejects.select{|y| y.is_a?(Regexp) and x =~ y}.empty? ||
62
+ attachment_rejects.include?(x)
43
63
  end
64
+ attrs_for_form | attachments
44
65
  end
45
66
 
67
+ # Base this on has_attached_file
46
68
  def attr_form_method(kls, attr)
69
+ # consolidate x_file_name, x_content_type and x_file_size to just x and use file_field
70
+ return :file_field if atts = attachments_for(kls) and atts.include?(attr)
47
71
  case kls.columns.find{|c| c.name == attr}.try(:type)
48
72
  when :string, :integer, :float, :decimal, :datetime, :timestamp, :time, :date
49
73
  # using text fields for the date selectors b/c most people will use a js calendar
@@ -56,14 +80,31 @@ module Skizmo
56
80
  return :text_field
57
81
  end
58
82
  end
83
+
84
+ def attachments_for(kls)
85
+ if atts = kls.try(:attachment_definitions)
86
+ return atts.keys
87
+ else
88
+ return nil
89
+ end
90
+ end
59
91
 
92
+ def have_attachments?
93
+ (has_many_classes | belongs_to_classes).each do |kls|
94
+ return true if attachments_for(kls.to_s.classify.constantize)
95
+ end
96
+ return false
97
+ end
98
+
99
+ def nested_attributes
100
+ cls.nested_attributes_options.keys
101
+ end
102
+
60
103
  def class_reflections
61
104
  cls.reflections
62
105
  end
63
106
 
64
- # TODO only get the classes that have "nested attributes"
65
-
66
- def nested_has_many_classes
107
+ def has_many_classes
67
108
  has_many_through_associations = class_reflections.select{|k,v| v.macro == :has_many and v.options.has_key?(:through)}
68
109
  through_assocs = has_many_through_associations.map{|x| x.last.options[:through]}
69
110
  # we don't care about the associations that primarily exist to assist the has_many :through
@@ -73,10 +114,28 @@ module Skizmo
73
114
  # these are the keys of the reflections we care about
74
115
  (has_many_through_associations | has_many_associations).map(&:first)
75
116
  end
117
+
118
+ # only get the classes that have "nested attributes"
119
+ def nested_has_many_classes
120
+ has_many_classes.select{|k| nested_attributes.include?(k)}
121
+ end
76
122
 
77
- def nested_belongs_to_classes
123
+ def non_nested_has_many_classes
124
+ has_many_classes.select{|k| !nested_attributes.include?(k)}
125
+ end
126
+
127
+ def belongs_to_classes
78
128
  class_reflections.select{|k,v| v.macro == :belongs_to}.map(&:first)
79
129
  end
130
+
131
+ # only get the classes that have "nested attributes"
132
+ def nested_belongs_to_classes
133
+ belongs_to_classes.select{|k| nested_attributes.include?(k)}
134
+ end
135
+
136
+ def non_nested_belongs_to_classes
137
+ belongs_to_classes.select{|k| !nested_attributes.include?(k)}
138
+ end
80
139
 
81
140
  def nested_classes
82
141
  {:belongs_to => nested_belongs_to_classes, :has_many => nested_has_many_classes}
@@ -93,7 +152,6 @@ module Skizmo
93
152
  end
94
153
  to_return
95
154
  end
96
-
97
155
  end
98
156
  end
99
157
  end
@@ -1,4 +1,8 @@
1
- <%%= form_for @<%= cls.to_s.underscore %> do |f| %>
1
+ <% if options.helpers? -%>
2
+ <%%= form_for setup_<%= cls_underscore %>(@<%= cls.to_s.underscore %>)<%= @have_attachment_string %> do |f| %>
3
+ <% else -%>
4
+ <%%= form_for @<%= cls.to_s.underscore %><%= @have_attachment_string %> do |f| %>
5
+ <% end -%>
2
6
  <%% if @<%= cls.to_s.underscore %>.errors.any? %>
3
7
  <div id="errorExplanation">
4
8
  <h2><%%= pluralize(@<%= cls.to_s.underscore %>.errors.count, "error") %> prohibited this <%= cls.to_s.underscore.gsub("_"," ") %> from being saved:</h2>
@@ -15,6 +19,20 @@
15
19
  <%%= f.<%= attr_form_method(cls, att) %> :<%= att %> %>
16
20
  </div>
17
21
  <% end -%>
22
+ <% if options.select_boxes? -%>
23
+ <% non_nested_belongs_to_classes.each do |cls_name| -%>
24
+ <div class="field">
25
+ <%%= f.label :<%= cls_name %>_id, "<%= cls_name.to_s.underscore.gsub("_", " ").camelize %>" %>
26
+ <%%= f.select :<%= cls_name %>_id, build_select_list(:<%= cls_name %>), {:prompt => "Please select one"} %>
27
+ </div>
28
+ <% end -%>
29
+ <% non_nested_has_many_classes.each do |cls_name| -%>
30
+ <div class="field">
31
+ <%%= f.label :<%= cls_name.to_s.singularize %>_ids, "<%= cls_name.to_s.underscore.gsub("_", " ").camelize %>" %>
32
+ <%%= f.select :<%= cls_name.to_s.singularize %>_ids, build_select_list(:<%= cls_name %>), {:prompt => "Please select"}, {:multiple => true, :size => 4} %>
33
+ </div>
34
+ <% end -%>
35
+ <% end -%>
18
36
  <% nested_belongs_to_classes.each do |cls_name| -%>
19
37
  <%%= f.fields_for :<%= cls_name %> do |nf| %>
20
38
  <%%= render '<%= cls_name.to_s.singularize.underscore %>_fields', :f => nf %>
@@ -0,0 +1,25 @@
1
+ module <%= cls_classname %>SetupHelper
2
+ def setup_<%= cls_underscore %>(obj)
3
+ <% nested_belongs_to_classes.each do |cls_name| -%>
4
+ obj.build_<%= cls_name %> if obj.<%= cls_name %>.blank?
5
+ <% end -%>
6
+ <% nested_has_many_classes.each do |cls_name| -%>
7
+ obj.<%= cls_name %>.build if obj.<%= cls_name %>.empty?
8
+ <% end -%>
9
+ return obj
10
+ end
11
+
12
+ <% if options.select_boxes? -%>
13
+ def build_select_list(assoc, options={})
14
+ name = options[:name] || "name"
15
+ scope = options[:scope] || "all"
16
+ begin
17
+ # name and id associations
18
+ assoc.to_s.classify.constantize.send(scope).map{|a| [a.send(name), a.id]}
19
+ rescue
20
+ # use id for text and value
21
+ assoc.to_s.classify.constantize.send(scope).map(&:id)
22
+ end
23
+ end
24
+ <% end -%>
25
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: formgen
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 0.1.0
10
+ version: 0.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pullmonkey
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-11-15 00:00:00 -07:00
18
+ date: 2011-11-16 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -86,14 +86,12 @@ extensions: []
86
86
 
87
87
  extra_rdoc_files:
88
88
  - LICENSE.txt
89
- - README
90
89
  - README.rdoc
91
90
  files:
92
91
  - .document
93
92
  - Gemfile
94
93
  - Gemfile.lock
95
94
  - LICENSE.txt
96
- - README
97
95
  - README.rdoc
98
96
  - Rakefile
99
97
  - VERSION
@@ -107,6 +105,7 @@ files:
107
105
  - lib/generators/skizmo/form/templates/helper.rb
108
106
  - lib/generators/skizmo/form/templates/javascript.js
109
107
  - lib/generators/skizmo/form/templates/new.html.erb
108
+ - lib/generators/skizmo/form/templates/setup_helper.rb
110
109
  - test/helper.rb
111
110
  - test/test_formgen.rb
112
111
  has_rdoc: true
data/README DELETED
@@ -1,40 +0,0 @@
1
- rails g skizmo:form --help
2
- Usage:
3
- rails generate skizmo:form NAME [options]
4
-
5
- Options:
6
- [--javascript] # Indicates when to generate javascript
7
- # Default: true
8
- [--helpers] # Indicates when to generate helpers
9
- # Default: true
10
-
11
- Runtime options:
12
- -p, [--pretend] # Run but do not make any changes
13
- -s, [--skip] # Skip files that already exist
14
- -q, [--quiet] # Supress status output
15
- -f, [--force] # Overwrite files that already exist
16
-
17
- Description:
18
- Generates a form per usual but with fields_for for the has_many and belongs_to associations.
19
-
20
- Example:
21
- rails generate skizmo:form Foo
22
-
23
- With Foo.rb (model like this):
24
- class Foo < ActiveRecord::Base
25
- has_many :bars
26
- belongs_to :baz
27
-
28
- accepts_nested_attributes_for :bars
29
- accepts_nested_attributes_for :baz
30
- end
31
-
32
- This will create:
33
- public/javascripts/jquery.add_remove_links.js
34
- app/helpers/add_remove_links_helper.rb
35
- app/views/foos/new.html.erb
36
- app/views/foos/edit.html.erb
37
- app/views/foos/_form.html.erb
38
- app/views/foos/_bar_fields.html.erb
39
- app/views/foos/_baz_fields.html.erb
40
-