common_core_js 0.0.2.alpha → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.generators +8 -0
  3. data/.gitignore +14 -0
  4. data/.rakeTasks +7 -0
  5. data/Gemfile +15 -0
  6. data/Gemfile.lock +175 -0
  7. data/LICENSE +10 -0
  8. data/README.md +288 -0
  9. data/Rakefile +32 -0
  10. data/app/assets/config/common_core_js_manifest.js +1 -0
  11. data/app/assets/images/common_core_js/.keep +0 -0
  12. data/app/assets/stylesheets/common_core_js/application.css +15 -0
  13. data/app/assets/stylesheets/common_core_js/common_core.scss +43 -0
  14. data/app/controllers/common_core_js/application_controller.rb +5 -0
  15. data/app/helpers/common_core_js/application_helper.rb +4 -0
  16. data/app/helpers/common_core_js/generator_helper.rb +0 -0
  17. data/app/jobs/common_core_js/application_job.rb +4 -0
  18. data/app/mailers/common_core_js/application_mailer.rb +6 -0
  19. data/app/models/common_core_js/application_record.rb +5 -0
  20. data/app/views/common/_common_create.js.erb +1 -1
  21. data/app/views/common/_common_destroy.js.erb +1 -1
  22. data/app/views/common/_common_index.js.erb +1 -1
  23. data/app/views/common/_common_new_form.haml +2 -2
  24. data/app/views/common/_common_update.js.erb +1 -1
  25. data/app/views/layouts/common_core_js/application.html.erb +15 -0
  26. data/bin/rails +14 -0
  27. data/common_core_js.gemspec +70 -0
  28. data/config/routes.rb +2 -0
  29. data/lib/.DS_Store +0 -0
  30. data/lib/common_core_js.rb +5 -6
  31. data/lib/common_core_js/engine.rb +5 -0
  32. data/lib/common_core_js/version.rb +3 -0
  33. data/lib/generators/common_core/USAGE +2 -4
  34. data/lib/generators/common_core/install_generator.rb +23 -0
  35. data/lib/generators/common_core/scaffold_generator.rb +300 -35
  36. data/lib/generators/common_core/templates/_edit.haml +1 -1
  37. data/lib/generators/common_core/templates/_form.haml +1 -0
  38. data/lib/generators/common_core/templates/_line.haml +3 -0
  39. data/lib/generators/common_core/templates/_list.haml +1 -1
  40. data/lib/generators/common_core/templates/_new.haml +3 -1
  41. data/lib/generators/common_core/templates/all.haml +4 -0
  42. data/lib/generators/common_core/templates/common_core.js +37 -0
  43. data/lib/generators/common_core/templates/common_core.scss +0 -0
  44. data/lib/generators/common_core/templates/controller.rb +21 -10
  45. data/lib/generators/common_core/templates/controller_spec.rb +110 -0
  46. data/lib/generators/common_core/templates/edit.js.erb +1 -1
  47. data/lib/generators/common_core/templates/update.js.erb +1 -1
  48. data/lib/tasks/common_core_js_tasks.rake +7 -0
  49. metadata +132 -38
  50. data/app/assets/config/manifest.js +0 -3
  51. data/lib/version.rb +0 -4
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'CommonCoreJs'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ end
31
+
32
+ task default: :test
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/common_core_js .css
File without changes
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,43 @@
1
+
2
+ [data-role='close-button'] {
3
+ position: absolute;
4
+ top: 0;
5
+ right: 0;
6
+ }
7
+
8
+
9
+ i {
10
+ cursor: pointer;
11
+ }
12
+
13
+
14
+ .show-area{
15
+ span.content {
16
+ background-color: #ddd;
17
+ padding: 0px 6px;
18
+ display: inline-block;
19
+ }
20
+ }
21
+
22
+
23
+ td.paginate{
24
+ position: relative;
25
+ }
26
+
27
+ nav.pagination {
28
+ display: block;
29
+ text-align: right;
30
+ right: 0;
31
+ top: 0;
32
+
33
+ font-size: 1.1em;
34
+
35
+ span {
36
+ margin: 0 2px;
37
+ }
38
+ span.page.current {
39
+ color: black;
40
+ text-decoration: underline;
41
+
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ module CommonCoreJs
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module CommonCoreJs
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module CommonCoreJs
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module CommonCoreJs
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module CommonCoreJs
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -8,7 +8,7 @@
8
8
 
9
9
  <% if object.errors.any? %>
10
10
  $(".flash-notices").html("<%= j render 'layouts/flash_notices' %>");
11
- $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").html("<%= j render(partial: 'dashboard/errors', locals: {resource: object}) %>")
11
+ $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").html("<%= j render(partial: '#{controller.namespace}errors', locals: {resource: object}) %>")
12
12
  $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").append("<%= j render(partial: "new", locals: { singular.to_sym => object}) %><i class='fa fa-times-circle fa-2x' data-name='<%=singular%>' data-role='close-button' />").slideDown();
13
13
  <% else %>
14
14
  $("<%= (scope + " ") if controller.common_scope %> .new-<%=singular%>-form").slideUp();
@@ -7,5 +7,5 @@ $(".<%= singular %>-list table tr[data-id=<%= object.id %>]").fadeOut(750,functi
7
7
 
8
8
  <% else %>
9
9
  $(".flash-notices").html("<%= j render 'layouts/flash_notices' %>");
10
- $(".<%= singular %>-list").html("<%= j render(partial: 'dashboard/errors', locals: {resource: object}) %><br/<%= j render partial: "list", locals: {plural.to_sym => all_objects} %>")
10
+ $(".<%= singular %>-list").html("<%= j render(partial: '#{controller.namespace}errors', locals: {resource: object}) %><br/<%= j render partial: "list", locals: {plural.to_sym => all_objects} %>")
11
11
  <% end %>
@@ -1 +1 @@
1
- $('.<%= singular %>-list').html("<%= j render partial: "dashboard/#{plural}/list", locals: {plural.to_sym => objects} %>")
1
+ $('.<%= singular %>-list').html("<%= j render partial: "#{controller.namespace}#{plural}/list", locals: {plural.to_sym => objects} %>")
@@ -2,8 +2,8 @@
2
2
  New
3
3
  = singular.titlecase
4
4
 
5
- = form_with model: object, url: url, method: "post" do |f|
6
- = render partial: "dashboard/#{plural}/form", locals: {singular.to_sym => object, f: f}
5
+ = form_with model: object, url: url, method: "post", remote: true do |f|
6
+ = render partial: "#{controller.namespace}#{plural}/form", locals: {singular.to_sym => object, f: f}
7
7
 
8
8
  .row
9
9
  .col-md-12
@@ -1,6 +1,6 @@
1
1
  <% if object.errors.any? %>
2
2
  <% pass_through_locals ||= {} %>
3
- $(".<%= singular %>-table tr[data-id=<%= object.id %>][data-edit='true']").html("<%= j render(partial: 'dashboard/errors', locals: {resource: object}) %><%= j render partial: 'edit', locals: {singular.to_sym => object, url: url, colspan: controller.default_colspan}.merge(pass_through_locals || {}) %>")
3
+ $(".<%= singular %>-table tr[data-id=<%= object.id %>][data-edit='true']").html("<%= j render(partial: '#{controller.namespace}errors', locals: {resource: object}) %><%= j render partial: 'edit', locals: {singular.to_sym => object, url: url, colspan: controller.default_colspan}.merge(pass_through_locals || {}) %>")
4
4
  $(".flash-notices").html("<%= j render 'layouts/flash_notices' %>");
5
5
  <% else %>
6
6
  $(".<%= singular %>-table tr[data-id=<%= object.id %>]:not([data-edit='true'])").replaceWith("<%= j render partial: 'line', locals: {singular.to_sym => object } %>").fadeIn()
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Common core js</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "common_core_js/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails gems
3
+ # installed from the root of your application.
4
+
5
+ ENGINE_ROOT = File.expand_path('..', __dir__)
6
+ ENGINE_PATH = File.expand_path('../lib/common_core_js/engine', __dir__)
7
+ APP_PATH = File.expand_path('../test/dummy/config/application', __dir__)
8
+
9
+ # Set up gems listed in the Gemfile.
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
11
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
12
+
13
+ require 'rails/all'
14
+ require 'rails/engine/commands'
@@ -0,0 +1,70 @@
1
+ $:.push File.expand_path("lib", __dir__)
2
+
3
+ # Maintain your gem's version:
4
+ require "common_core_js/version"
5
+ require 'byebug'
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "common_core_js"
9
+ spec.version = CommonCoreJs::VERSION
10
+ spec.license = 'MIT'
11
+ spec.date = '2020-06-28'
12
+ spec.summary = "A gem build scaffolding."
13
+ spec.description = "Simple, plug & play Rails scaffolding with really simple Javascript"
14
+ spec.authors = ["Jason Fleetwood-Boldt"]
15
+ spec.email = 'jason.fb@datatravels.com'
16
+
17
+
18
+
19
+
20
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
21
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
22
+ if spec.respond_to?(:metadata)
23
+ spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
24
+ else
25
+ raise "RubyGems 2.0 or newer is required to protect against " \
26
+ "public gem pushes."
27
+ end
28
+
29
+ # spec.files = Dir["{app,config,db,lib,vendor}/**/*", "LICENSE", "Rakefile", "README.md"]
30
+
31
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+
35
+ spec.add_dependency "rails"
36
+ spec.homepage = 'https://blog.jasonfleetwoodboldt.com/common-core-js/'
37
+ spec.metadata = { "source_code_uri" => "https://github.com/jasonfb/common_core_js",
38
+ "documentation_uri" => "https://github.com/jasonfb/common_core_js",
39
+ "homepage_uri" => 'https://blog.jasonfleetwoodboldt.com/common-core-js/',
40
+ "mailing_list_uri" => 'https://blog.jasonfleetwoodboldt.com/#sfba-form2-container'
41
+ }
42
+
43
+ spec.add_runtime_dependency('kaminari')
44
+ spec.add_runtime_dependency('haml-rails')
45
+ spec.add_runtime_dependency "sass-rails"
46
+
47
+ spec.add_runtime_dependency 'bootsnap'
48
+ spec.add_runtime_dependency 'bootstrap'
49
+ spec.add_runtime_dependency 'font-awesome-rails'
50
+ spec.add_dependency 'ffaker'
51
+
52
+ spec.post_install_message = <<~MSG
53
+ ---------------------------------------------
54
+ Welcome to Common Core
55
+
56
+ rails generate common_score:scaffold Thing
57
+
58
+ * Build plug-and-play scaffolding mixing HAML with jQuery-based Javascript
59
+ * Automatically Reads Your Models (make them before building your scaffolding!)
60
+ * Excellent for CRUD, lists with pagination, searching, sorting.
61
+ * Wonderful for prototyping.
62
+ * Plays nicely with Devise, Kaminari, Haml-Rails, Rspec.
63
+ * Create specs autoamatically along with the controllers.
64
+ * Nest your routes model-by-model for built-in poor man's authentication
65
+ * Throw the scaffolding away when your app is ready to graduate to its next phase.
66
+
67
+ see README for complete instructions.
68
+ ---------------------------------------------
69
+ MSG
70
+ end
@@ -0,0 +1,2 @@
1
+ CommonCoreJs::Engine.routes.draw do
2
+ end
Binary file
@@ -1,10 +1,9 @@
1
-
2
-
3
- puts "*** Loading CommongCoreJS .........."
1
+ require "common_core_js/engine"
4
2
 
5
3
  require 'kaminari'
6
4
  require 'haml-rails'
7
5
 
8
- module CommonCoreJS
9
- require "nonschema_migrations/railtie.rb" if defined?(Rails)
10
- end
6
+
7
+ module CommonCoreJs
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,5 @@
1
+ module CommonCoreJs
2
+ class Engine < ::Rails::Engine
3
+ # isolate_namespace CommonCoreJs
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module CommonCoreJs
2
+ VERSION = '0.3.2'
3
+ end
@@ -1,8 +1,6 @@
1
1
  Description:
2
- Explain the generator
2
+ Generate a controller, view files, and spec
3
3
 
4
4
  Example:
5
- rails generate common_core_scaffold Thing
5
+ rails generate common_core:scaffold Thing
6
6
 
7
- This will create:
8
- what/will/it/create
@@ -0,0 +1,23 @@
1
+ require 'rails/generators/erb/scaffold/scaffold_generator'
2
+ require 'ffaker'
3
+
4
+ module CommonCore
5
+ class InstallGenerator < Rails::Generators::Base
6
+ hook_for :form_builder, :as => :scaffold
7
+
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+
11
+ def initialize(*args) #:nodoc:
12
+ super
13
+
14
+ copy_file "common_core.js", "vendor/assets/javascripts/common_core.js"
15
+ copy_file "common_core.scss", "vendor/assets/stylesheets/common_core.scss"
16
+
17
+ end
18
+
19
+ end
20
+ end
21
+
22
+
23
+
@@ -1,15 +1,46 @@
1
1
  require 'rails/generators/erb/scaffold/scaffold_generator'
2
+ require 'ffaker'
3
+
4
+
2
5
 
3
6
  module CommonCore
4
- class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
+
8
+ module GeneratorHelper
9
+ def text_area_output(col, field_length)
10
+ lines = field_length % 40
11
+ if lines > 5
12
+ lines = 5
13
+ end
14
+
15
+ ".row
16
+ .form-group.col-md-4
17
+ = f.text_area :#{col.to_s}, class: 'form-control', cols: 40, rows: '#{lines}'
18
+ %label.form-text
19
+ #{col.to_s.humanize}\n"
20
+ end
5
21
 
6
22
 
23
+
24
+ def field_output(col, type = nil, width)
25
+ ".row
26
+ .form-group.col-md-4
27
+ = f.text_field :#{col.to_s}, value: @#{singular}.#{col.to_s}, size: #{width}, class: 'form-control', type: '#{type}'
28
+ %label.form-text
29
+ #{col.to_s.humanize}\n"
30
+ end
31
+ end
32
+
33
+
34
+ class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
35
  hook_for :form_builder, :as => :scaffold
8
36
 
9
37
  source_root File.expand_path('templates', __dir__)
10
38
  attr_accessor :path, :singular, :plural, :singular_class, :nest_with
11
39
 
12
40
 
41
+ include GeneratorHelper
42
+
43
+
13
44
  def initialize(*meta_args) #:nodoc:
14
45
  super
15
46
 
@@ -20,21 +51,12 @@ module CommonCore
20
51
  exit
21
52
  end
22
53
 
23
- begin
24
- @columns = object.columns.map(&:name).map(&:to_sym).reject{|x| x==:updated_at || x==:created_at || x==:id}
25
- rescue StandardError => e
26
- puts "Ooops... it looks like is an object for #{class_name}. Please create the database table with fields first. "
27
- exit
28
- end
54
+
29
55
 
30
56
  args = meta_args[0]
31
57
  @singular = args[0].tableize.singularize # should be in form hello_world
32
58
 
33
59
 
34
-
35
-
36
-
37
-
38
60
  @plural = @singular + "s" # supply to override; leave blank to use default
39
61
  @singular_class = @singular.titleize.gsub(" ", "")
40
62
  @nest = nil
@@ -61,7 +83,17 @@ module CommonCore
61
83
  end
62
84
  end
63
85
 
86
+ auth_assoc = @auth.gsub("current_","")
87
+ auth_assoc_field = auth_assoc + "_id"
88
+
64
89
 
90
+ begin
91
+ @columns = object.columns.map(&:name).map(&:to_sym).reject{|field| field==:updated_at ||
92
+ field==:created_at || field==:id || field == auth_assoc_field.to_sym }
93
+ rescue StandardError => e
94
+ puts "Ooops... it looks like is an object for #{class_name}. Please create the database table with fields first. "
95
+ exit
96
+ end
65
97
 
66
98
  flags = meta_args[1]
67
99
  flags.each do |f|
@@ -70,12 +102,19 @@ module CommonCore
70
102
  @auth = nil
71
103
  when "--with-index"
72
104
  @with_index = true
105
+ when "--specs-only"
106
+ @specs_only = true
107
+ when "--no-specs"
108
+ @no_specs = true
73
109
  end
74
110
  end
75
111
 
112
+ if @specs_only && @no_specs
113
+ puts "oops… you seem to have specified both the --specs-only flag and --no-specs flags. this doesn't make any sense, so I am aborting. sorry."
114
+ exit
115
+ end
76
116
 
77
-
78
- if @auth_identifier.nil?
117
+ if @auth_identifier.nil? && !@auth.nil?
79
118
  @auth_identifier = @auth.gsub("current_", "")
80
119
  end
81
120
 
@@ -86,7 +125,6 @@ module CommonCore
86
125
  @nested_args.each do |a|
87
126
  @nested_args_plural[a] = a + "s"
88
127
  end
89
-
90
128
  end
91
129
  end
92
130
 
@@ -99,20 +137,75 @@ module CommonCore
99
137
  end
100
138
 
101
139
  def copy_controller_and_spec_files
102
-
103
140
  @default_colspan = @columns.size
104
- template "controller.rb", File.join("app/controllers", "#{plural}_controller.rb")
105
- # template "index", File.join("app/views", "app/views/#{self.name.downcase}/index")
106
141
 
107
- end
142
+ unless @specs_only
143
+ template "controller.rb", File.join("app/controllers#{namespace_with_dash}", "#{plural}_controller.rb")
144
+ end
108
145
 
146
+ unless @no_specs
147
+ template "controller_spec.rb", File.join("spec/controllers#{namespace_with_dash}", "#{plural}_controller_spec.rb")
148
+ end
149
+ end
109
150
 
110
151
  def list_column_headings
111
152
  @columns.map(&:to_s).map{|col_name| ' %th{:scope => "col"} ' + col_name.humanize}.join("\r")
112
153
  end
113
154
 
155
+ def columns_spec_with_sample_data
156
+ @columns.map { |c|
157
+ if eval("#{singular_class}.columns_hash['#{c}']").nil?
158
+ byebug
159
+ end
160
+ type = eval("#{singular_class}.columns_hash['#{c}']").type
161
+ random_data = case type
162
+ when :integer
163
+ rand(1...1000)
164
+ when :string
165
+ FFaker::AnimalUS.common_name
166
+ when :text
167
+ FFaker::AnimalUS.common_name
168
+ when :datetime
169
+ Time.now + rand(1..5).days
170
+ end
171
+ c.to_s + ": '" + random_data.to_s + "'"
172
+ }.join(", ")
173
+ end
174
+
175
+ def object_parent_mapping_as_argument_for_specs
176
+ if @nested_args.any?
177
+ ", " + @nested_args.last + ": " + @nested_args.last
178
+ elsif @auth
179
+ ", #{@auth_identifier}: #{@auth}"
180
+ end
181
+ end
182
+
183
+ def objest_nest_factory_setup
184
+ res = ""
185
+ if @auth
186
+ last_parent = ", #{@auth_identifier}: #{@auth}"
187
+ end
188
+
189
+ @nested_args.each do |arg|
190
+ res << " let(:#{arg}) {create(:#{arg} #{last_parent} )}\n"
191
+ last_parent = ", #{arg}: #{arg}"
192
+ end
193
+ res
194
+ end
195
+
196
+
197
+ def objest_nest_params_by_id_for_specs
198
+ @nested_args.map{|arg|
199
+ "#{arg}_id: #{arg}.id"
200
+ }.join(",\n ")
201
+ end
202
+
203
+
114
204
  def controller_class_name
115
- plural.titleize.gsub(" ", "") + "Controller"
205
+ res = ""
206
+ res << @namespace.titleize + "::" if @namespace
207
+ res << plural.titleize.gsub(" ", "") + "Controller"
208
+ res
116
209
  end
117
210
 
118
211
  def singular_name
@@ -128,20 +221,26 @@ module CommonCore
128
221
  end
129
222
 
130
223
 
131
- def path_helper
132
- "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
224
+ def path_helper_singular
225
+ "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{singular}_path"
133
226
  end
134
227
 
228
+ def path_helper_plural
229
+ "#{@namespace+"_" if @namespace}#{(@nested_args.join("_") + "_" if @nested_args.any?)}#{plural}_path"
230
+ end
135
231
 
136
232
  def path_arity
137
- (nested_objects_arity + ", " if @nested_args) + "@" + singular
233
+ res = ""
234
+ if @nested_args.any?
235
+ res << nested_objects_arity + ", "
236
+ end
237
+ res << "@" + singular
138
238
  end
139
239
 
140
240
  def line_path_partial
141
- "#{@namespace+"/" if @namespace}#{singular}/line"
241
+ "#{@namespace+"/" if @namespace}#{plural}/line"
142
242
  end
143
243
 
144
-
145
244
  def nested_assignments
146
245
  @nested_args.map{|a| "#{a}: @#{a}"}.join(", ") #metaprgramming into Ruby hash
147
246
  end
@@ -156,13 +255,26 @@ module CommonCore
156
255
 
157
256
  def object_scope
158
257
  if @auth
159
- if @nested_args.any?
160
- @auth
258
+ if @nested_args.none?
259
+ @auth + ".#{plural}"
260
+ else
261
+ "@" + @nested_args.last + ".#{plural}"
262
+ end
263
+ else
264
+ @singular_class
265
+ end
266
+ end
267
+
268
+
269
+ def all_objects_root
270
+ if @auth
271
+ if @nested_args.none?
272
+ @auth + ".#{plural}"
161
273
  else
162
- "@" + @nested_args.last + "s"
274
+ "@" + @nested_args.last + ".#{plural}"
163
275
  end
164
276
  else
165
- class_name
277
+ @singular_class + ".all"
166
278
  end
167
279
  end
168
280
 
@@ -172,7 +284,7 @@ module CommonCore
172
284
 
173
285
  def all_objects_variable
174
286
  # needs the authenticated root user
175
- "#{@auth}#{'.' + @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args}#{plural}"
287
+ "#{@auth}.#{ @nested_args.map{|a| "#{@nested_args_plural[a]}.find(@#{a})"}.join('.') + "." if @nested_args.any?}#{plural}"
176
288
  end
177
289
 
178
290
  def auth_object
@@ -180,29 +292,49 @@ module CommonCore
180
292
  end
181
293
 
182
294
  def copy_view_files
295
+ return if @specs_only
183
296
  js_views.each do |view|
184
297
  formats.each do |format|
185
-
186
298
  filename = cc_filename_with_extensions(view, ["js","erb"])
187
- template filename, File.join("app/views", controller_file_path, filename)
299
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
188
300
  end
189
301
  end
190
302
 
303
+
191
304
  haml_views.each do |view|
192
305
  formats.each do |format|
193
-
194
306
  filename = cc_filename_with_extensions(view, "haml")
195
- template filename, File.join("app/views", controller_file_path, filename)
307
+ template filename, File.join("app/views#{namespace_with_dash}", controller_file_path, filename)
196
308
  end
197
309
  end
198
310
  end
199
311
 
312
+ def namespace_with_dash
313
+ if @namespace
314
+ "/#{@namespace}"
315
+ else
316
+ ""
317
+ end
318
+ end
319
+
320
+ def namespace_with_trailing_dash
321
+ if @namespace
322
+ "#{@namespace}/"
323
+ else
324
+ ""
325
+ end
326
+ end
327
+
200
328
  def js_views
201
329
  %w(index create destroy edit new update)
202
330
  end
203
331
 
204
332
  def haml_views
205
- %w(_edit _form _line _list _new)
333
+ res = %w(_edit _form _line _list _new)
334
+ if @with_index
335
+ res << 'all'
336
+ end
337
+ res
206
338
  end
207
339
 
208
340
 
@@ -213,10 +345,143 @@ module CommonCore
213
345
 
214
346
  def create_merge_params
215
347
  if @auth
216
- ".merge!(#{@auth_identifier}: #{@auth})"
348
+ "#{@auth_identifier}: #{@auth}"
349
+ else
350
+ ""
217
351
  end
218
352
  end
219
353
 
354
+ def model_has_strings?
355
+ false
356
+ end
357
+
358
+
359
+ def model_search_fields # an array of fields we can search on
360
+ []
361
+ end
362
+
363
+ def all_form_fields
364
+ res = @columns.map { |col|
365
+
366
+
367
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
368
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
369
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
370
+
371
+ case type
372
+ when :integer
373
+ # look for a belongs_to on this object
374
+ if col.to_s.ends_with?("_id")
375
+ # guess the association name label
376
+
377
+
378
+ assoc_name = col.to_s.gsub("_id","")
379
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
380
+ if assoc.nil?
381
+ puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
382
+ exit
383
+ end
384
+
385
+ if assoc.active_record.column_names.include?("name")
386
+ display_column = "name"
387
+ elsif assoc.active_record.column_names.include?("to_label")
388
+ display_column = "to_label"
389
+ elsif assoc.active_record.column_names.include?("full_name")
390
+ display_column = "full_name"
391
+ elsif assoc.active_record.column_names.include?("display_name")
392
+ display_column = "display_name"
393
+ elsif assoc.active_record.column_names.include?("email")
394
+ display_column = "email"
395
+ end
396
+
397
+ ".row
398
+ .form-group.col-md-4
399
+ = f.collection_select(:#{col.to_s}, #{assoc_name.titleize}.all, :id, :#{display_column}, {prompt: true, selected: @#{singular}.#{col.to_s} , class: 'form-control')
400
+ %label.small.form-text.text-muted
401
+ #{col.to_s.humanize}"
402
+
403
+ else
404
+ ".row
405
+ .form-group.col-md-4
406
+ = f.text_field :#{col.to_s}, value: @#{singular}.#{col.to_s}, class: 'form-control', size: 4, type: 'number'
407
+ %label.form-text
408
+ #{col.to_s.humanize}\n"
409
+ end
410
+ when :string
411
+ limit ||= 40
412
+ if limit < 50
413
+ field_output(col, nil, limit)
414
+ else
415
+ text_area_output(col, limit)
416
+ end
417
+
418
+ when :text
419
+ limit ||= 40
420
+ if limit < 50
421
+ field_output(col, nil, limit)
422
+ else
423
+ text_area_output(col, limit)
424
+ end
425
+
426
+ when :datetime
427
+ ".row
428
+ .form-group.col-md-4
429
+ = f.text_field :#{col.to_s}, value: @#{singular}.#{col.to_s}, class: 'form-control', type: 'datetime-local'
430
+ %label.form-text
431
+ #{col.to_s.humanize}\n"
432
+ end
433
+ }.join("\n")
434
+ return res
435
+ end
436
+
437
+
438
+ def all_line_fields
439
+ res = "%tr{'data-id': #{singular}.id, 'data-edit': 'false'}\n"
440
+
441
+ res << @columns.map { |col|
442
+ type = eval("#{singular_class}.columns_hash['#{col}']").type
443
+ limit = eval("#{singular_class}.columns_hash['#{col}']").limit
444
+ sql_type = eval("#{singular_class}.columns_hash['#{col}']").sql_type
445
+
446
+ case type
447
+ when :integer
448
+ # look for a belongs_to on this object
449
+ if col.to_s.ends_with?("_id")
450
+
451
+ assoc_name = col.to_s.gsub("_id","")
452
+
453
+
454
+ assoc = eval("#{singular_class}.reflect_on_association(:#{assoc_name})")
455
+
456
+ if assoc.nil?
457
+ puts "*** Oops. on the #{singular_class} object, there doesn't seem to be an association called '#{assoc_name}'"
458
+ exit
459
+ end
460
+
461
+ " %td
462
+ = #{singular}.#{assoc.name.to_s}.to_label"
463
+
464
+ else
465
+ " %td
466
+ = #{singular}.#{col}"
467
+ end
468
+ when :string
469
+ width = (limit && limit < 40) ? limit : (40)
470
+ " %td
471
+ = #{singular}.#{col}"
472
+ when :text
473
+ " %td
474
+ = #{singular}.#{col}"
475
+ when :datetime
476
+ " %td
477
+ = #{singular}.#{col}"
478
+ end
479
+ }.join("\n")
480
+ return res
481
+ end
482
+
483
+
484
+
220
485
  private # thor does something fancy like sending the class all of its own methods during some strange run sequence
221
486
  # does not like public methods
222
487