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.
- data/LICENSE.txt +1 -1
- data/README.rdoc +26 -8
- data/VERSION +1 -1
- data/formgen.gemspec +3 -4
- data/lib/generators/skizmo/form/USAGE +4 -1
- data/lib/generators/skizmo/form/form_generator.rb +68 -10
- data/lib/generators/skizmo/form/templates/_form.html.erb +19 -1
- data/lib/generators/skizmo/form/templates/setup_helper.rb +25 -0
- metadata +5 -6
- data/README +0 -40
data/LICENSE.txt
CHANGED
data/README.rdoc
CHANGED
@@ -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
|
-
[--
|
9
|
-
|
10
|
-
[--
|
11
|
-
|
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
|
-
-
|
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
|
-
-
|
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.2.0
|
data/formgen.gemspec
CHANGED
@@ -5,16 +5,15 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{formgen}
|
8
|
-
s.version = "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-
|
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
|
-
|
37
|
+
cls_underscore
|
32
38
|
end
|
33
39
|
|
34
40
|
def cls
|
35
|
-
|
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
|
-
|
42
|
-
|
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
|
-
|
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
|
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
|
-
|
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:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 2
|
9
9
|
- 0
|
10
|
-
version: 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-
|
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
|
-
|