inline_forms 6.2.14 → 7.0.4

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +174 -0
  3. data/README.rdoc +13 -1
  4. data/Rakefile +12 -1
  5. data/app/helpers/form_elements/audio_field.rb +1 -1
  6. data/app/helpers/form_elements/check_box.rb +1 -1
  7. data/app/helpers/form_elements/check_list.rb +2 -2
  8. data/app/helpers/form_elements/chicas_dropdown_with_family_members.rb +1 -1
  9. data/app/helpers/form_elements/ckeditor.rb +2 -1
  10. data/app/helpers/form_elements/date.rb +1 -1
  11. data/app/helpers/form_elements/decimal_field.rb +1 -1
  12. data/app/helpers/form_elements/devise_password_field.rb +1 -1
  13. data/app/helpers/form_elements/dropdown.rb +1 -1
  14. data/app/helpers/form_elements/dropdown_with_integers.rb +1 -1
  15. data/app/helpers/form_elements/dropdown_with_other.rb +1 -1
  16. data/app/helpers/form_elements/dropdown_with_values.rb +1 -1
  17. data/app/helpers/form_elements/dropdown_with_values_with_stars.rb +1 -1
  18. data/app/helpers/form_elements/file_field.rb +1 -1
  19. data/app/helpers/form_elements/geo_code_curacao.rb +1 -1
  20. data/app/helpers/form_elements/image_field.rb +1 -1
  21. data/app/helpers/form_elements/integer_field.rb +1 -1
  22. data/app/helpers/form_elements/kansen_slider.rb +1 -1
  23. data/app/helpers/form_elements/money_field.rb +1 -1
  24. data/app/helpers/form_elements/month_select.rb +1 -1
  25. data/app/helpers/form_elements/month_year_picker.rb +1 -1
  26. data/app/helpers/form_elements/move.rb +1 -1
  27. data/app/helpers/form_elements/multi_image_field.rb +1 -1
  28. data/app/helpers/form_elements/plain_text_area.rb +1 -1
  29. data/app/helpers/form_elements/question_list.rb +2 -2
  30. data/app/helpers/form_elements/radio_button.rb +1 -1
  31. data/app/helpers/form_elements/rich_text.rb +36 -0
  32. data/app/helpers/form_elements/scale_with_integers.rb +1 -1
  33. data/app/helpers/form_elements/scale_with_values.rb +1 -1
  34. data/app/helpers/form_elements/simple_file_field.rb +1 -1
  35. data/app/helpers/form_elements/slider_with_values.rb +1 -1
  36. data/app/helpers/form_elements/text_area.rb +4 -3
  37. data/app/helpers/form_elements/text_area_without_ckeditor.rb +1 -1
  38. data/app/helpers/form_elements/text_field.rb +1 -1
  39. data/app/helpers/form_elements/time.rb +1 -1
  40. data/app/helpers/inline_forms_helper.rb +56 -29
  41. data/app/views/inline_forms/_close.html.erb +2 -2
  42. data/app/views/inline_forms/_edit.html.erb +5 -4
  43. data/app/views/inline_forms/_new.html.erb +2 -2
  44. data/app/views/inline_forms/_versions_list.html.erb +30 -14
  45. data/app/views/layouts/application.html.erb +3 -1
  46. data/app/views/layouts/inline_forms.html.erb +3 -1
  47. data/bin/inline_forms +1 -1
  48. data/bin/inline_forms_installer_core.rb +99 -27
  49. data/docs/prompt/.gitignore +5 -0
  50. data/docs/prompt/test-the-example-app.md +32 -0
  51. data/inline_forms.gemspec +3 -1
  52. data/lib/generators/inline_forms_generator.rb +30 -0
  53. data/lib/generators/templates/migration.erb +1 -1
  54. data/lib/generators/templates/model.erb +1 -0
  55. data/lib/inline_forms/form_element_from_callee.rb +10 -0
  56. data/lib/inline_forms/version.rb +1 -1
  57. data/lib/inline_forms.rb +1 -13
  58. data/lib/installer_templates/example_app_tests/test/example_app/example_integration_test_case.rb +36 -0
  59. data/lib/installer_templates/example_app_tests/test/integration/example_app_guest_access_test.rb +21 -0
  60. data/lib/installer_templates/example_app_tests/test/integration/example_app_photos_test.rb +22 -0
  61. data/lib/installer_templates/example_app_tests/test/integration/example_app_routing_test.rb +15 -0
  62. data/lib/installer_templates/example_app_tests/test/models/example_app_apartment_photo_test.rb +26 -0
  63. data/lib/installer_templates/example_app_tests/test/models/example_app_paper_trail_changeset_test.rb +78 -0
  64. data/test/form_element_from_callee_test.rb +73 -0
  65. data/test/inline_edit_polymorphic_path_test.rb +81 -0
  66. data/test/inline_forms_generator_test.rb +155 -0
  67. data/test/test_helper.rb +6 -0
  68. metadata +42 -11
  69. data/app/helpers/form_elements/absence_list.rb +0 -45
@@ -2,7 +2,7 @@
2
2
  InlineForms::SPECIAL_COLUMN_TYPES[:text_area_without_ckeditor]=:text
3
3
 
4
4
  def text_area_without_ckeditor_show(object, attribute)
5
- link_to_inline_edit object, attribute, (object[attribute].nil? || object[attribute].empty?) ? "<i class='fi-plus'></i>".html_safe : object[attribute]
5
+ link_to_inline_edit object, attribute, (object[attribute].nil? || object[attribute].empty?) ? "<i class='fi-plus'></i>".html_safe : object[attribute], from_callee: __callee__
6
6
  end
7
7
 
8
8
  def text_area_without_ckeditor_edit(object, attribute)
@@ -2,7 +2,7 @@
2
2
  InlineForms::SPECIAL_COLUMN_TYPES[:text_field]=:string
3
3
 
4
4
  def text_field_show(object, attribute)
5
- link_to_inline_edit object, attribute, object[attribute].blank? ? "<i class='fi-plus'></i>".html_safe : object[attribute]
5
+ link_to_inline_edit object, attribute, object[attribute].blank? ? "<i class='fi-plus'></i>".html_safe : object[attribute], from_callee: __callee__
6
6
  end
7
7
 
8
8
  def text_field_edit(object, attribute)
@@ -3,7 +3,7 @@
3
3
 
4
4
  # time
5
5
  def time_select_show(object, attribute)
6
- link_to_inline_edit object, attribute, object.send(attribute).nil? ? "<i class='fi-plus'></i>".html_safe : object.send(attribute).to_datetime.strftime("%l:%M%P")
6
+ link_to_inline_edit object, attribute, object.send(attribute).nil? ? "<i class='fi-plus'></i>".html_safe : object.send(attribute).to_datetime.strftime("%l:%M%P"), from_callee: __callee__
7
7
  end
8
8
 
9
9
  def time_select_edit(object, attribute)
@@ -12,6 +12,46 @@ module InlineFormsHelper
12
12
  InlineForms::VERSION
13
13
  end
14
14
 
15
+ # Returns versions for `object`, merged with versions of any associated
16
+ # `ActionText::RichText` records (Rails `has_rich_text :foo` declarations).
17
+ #
18
+ # Rich-text bodies live in the polymorphic `action_text_rich_texts` table,
19
+ # so `has_paper_trail` on the parent model (e.g. Apartment) never sees
20
+ # rich-text edits. The generated app installs an initializer
21
+ # (`config/initializers/rich_text_paper_trail.rb`) that declares
22
+ # `has_paper_trail` on `ActionText::RichText` itself; this helper is what
23
+ # surfaces those versions inside the parent's versions list view
24
+ # (`app/views/inline_forms/_versions_list.html.erb`).
25
+ #
26
+ # Each entry is a Hash:
27
+ # :version => the PaperTrail::Version
28
+ # :kind => :primary (parent model) or :rich_text
29
+ # :rich_text_name => for :rich_text entries, the attribute name
30
+ # (e.g. "description"); nil for :primary
31
+ #
32
+ # Sorted oldest-first (callers can `.reverse` for newest-first display).
33
+ def inline_forms_versions_for(object)
34
+ entries = object.versions.map do |v|
35
+ { version: v, kind: :primary, rich_text_name: nil }
36
+ end
37
+
38
+ if defined?(ActionText::RichText)
39
+ ActionText::RichText
40
+ .where(record_type: object.class.base_class.name, record_id: object.id)
41
+ .each do |rich_text|
42
+ rich_text.versions.each do |v|
43
+ entries << {
44
+ version: v,
45
+ kind: :rich_text,
46
+ rich_text_name: rich_text.name
47
+ }
48
+ end
49
+ end
50
+ end
51
+
52
+ entries.sort_by { |entry| entry[:version].created_at }
53
+ end
54
+
15
55
  private
16
56
 
17
57
  def validation_hints_as_list_for(object, attribute)
@@ -21,10 +61,10 @@ module InlineFormsHelper
21
61
  # close link
22
62
  def close_link( object, update_span, html_class = 'button close_button' )
23
63
  link_to "<i class='fi-x'></i>".html_safe,
24
- send( object.class.to_s.underscore + '_path',
25
- object,
26
- :update => update_span,
27
- :close => true ),
64
+ polymorphic_path(
65
+ object,
66
+ :update => update_span,
67
+ :close => true ),
28
68
  :remote => true,
29
69
  :class => html_class,
30
70
  :title => t('inline_forms.view.close')
@@ -60,9 +100,9 @@ module InlineFormsHelper
60
100
  hard=''
61
101
  if cancan_disabled? || ( can? :destroy, object )
62
102
  hard = link_to "&nbsp;&nbsp;<font color='FF0000'><i class='fi-x'></i></font>".html_safe,
63
- send( object.class.to_s.underscore + '_path',
64
- object,
65
- :update => update_span ),
103
+ polymorphic_path(
104
+ object,
105
+ :update => update_span ),
66
106
  :method => :delete,
67
107
  :remote => true,
68
108
  :title => t('inline_forms.view.trash')
@@ -127,7 +167,10 @@ module InlineFormsHelper
127
167
  end
128
168
 
129
169
  # link_to_inline_edit
130
- def link_to_inline_edit(object, attribute, attribute_value='', form_element=nil)
170
+ #
171
+ # Pass +from_callee:+ +__callee__+ from the enclosing +*_show+ method so the edit route receives the correct form element name.
172
+ def link_to_inline_edit(object, attribute, attribute_value='', from_callee:)
173
+ form_element = InlineForms.form_element_string_from_callee(from_callee)
131
174
  attribute_value = attribute_value.to_s
132
175
  spaces = attribute_value.length > 40 ? 0 : 40 - attribute_value.length
133
176
  value = h(attribute_value) + ("&nbsp;" * spaces).html_safe
@@ -135,11 +178,11 @@ module InlineFormsHelper
135
178
  if (cancan_disabled? rescue true) || ( can? :update, object, attribute )
136
179
  # some problem with concerns makes this function not available when called direct. FIXME
137
180
  link_to value,
138
- send( 'edit_' + object.class.to_s.underscore + '_path',
139
- object,
140
- :attribute => attribute.to_s,
141
- :form_element => form_element.nil? ? calling_method.sub(/_[a-z]+$/,'').sub(/block in /,'') : form_element,
142
- :update => css_class_id ),
181
+ edit_polymorphic_path(
182
+ object,
183
+ :attribute => attribute.to_s,
184
+ :form_element => form_element,
185
+ :update => css_class_id ),
143
186
  :remote => true
144
187
  else
145
188
  h(attribute_value)
@@ -223,19 +266,3 @@ module InlineFormsHelper
223
266
  end
224
267
 
225
268
  end
226
-
227
- module Kernel
228
- private
229
- # make the current method available
230
- # http://www.ruby-forum.com/topic/75258
231
- # supposedly, this is fixed in 1.9
232
- def this_method
233
- caller[0] =~ /`([^']*)'/ and $1
234
- end
235
- # make the calling method available
236
- # http://www.ruby-forum.com/topic/75258
237
- # supposedly, this is fixed in 1.9
238
- def calling_method
239
- caller[1] =~ /`([^']*)'/ and $1
240
- end
241
- end
@@ -4,10 +4,10 @@
4
4
  <%= link_to_destroy(@object, @update_span) -%>
5
5
  </div>
6
6
  <div class="small-11 column">
7
- <%= link_to h(@object._presentation), send(@object.class.to_s.underscore + "_path", @object, :update => @update_span), :remote => true -%>
7
+ <%= link_to h(@object._presentation), polymorphic_path(@object, :update => @update_span), :remote => true -%>
8
8
  </div>
9
9
  <% else %>
10
10
  <div class="small-12 column">
11
- <%= link_to h(@object._presentation), send(@object.class.to_s.underscore + "_path", @object, :update => @update_span), :remote => true -%>
11
+ <%= link_to h(@object._presentation), polymorphic_path(@object, :update => @update_span), :remote => true -%>
12
12
  </div>
13
13
  <% end %>
@@ -1,5 +1,6 @@
1
- <% @BUTTONS_UNDER = [ "text_area", "kansen_slider" ] %>
2
- <%= form_tag send(@object.class.to_s.underscore + '_path', :update => @update_span,
1
+ <% @BUTTONS_UNDER = [ "text_area", "kansen_slider", "rich_text" ] %>
2
+ <%= form_tag polymorphic_path(@object,
3
+ :update => @update_span,
3
4
  :attribute => @attribute,
4
5
  :form_element => @form_element,
5
6
  :sub_id => @sub_id ),
@@ -42,7 +43,7 @@
42
43
  <%= submit_tag "ok", :class => "postfix button"-%>
43
44
  </div>
44
45
  <div class="small-2 columns">
45
- <%= link_to( send( @object.class.to_s.underscore + '_path', :update => @update_span || "field_#{@attribute}_#{@object.id.to_s}",
46
+ <%= link_to( polymorphic_path( @object, :update => @update_span || "field_#{@attribute}_#{@object.id.to_s}",
46
47
  :attribute => @attribute,
47
48
  :form_element => @form_element,
48
49
  :sub_id => @sub_id ),
@@ -61,7 +62,7 @@
61
62
  <%= submit_tag "ok", :class => "postfix button"-%>
62
63
  </div>
63
64
  <div class="small-2 columns">
64
- <%= link_to( send( @object.class.to_s.underscore + '_path', :update => @update_span || "field_#{@attribute}_#{@object.id.to_s}",
65
+ <%= link_to( polymorphic_path( @object, :update => @update_span || "field_#{@attribute}_#{@object.id.to_s}",
65
66
  :attribute => @attribute,
66
67
  :form_element => @form_element,
67
68
  :sub_id => @sub_id ),
@@ -25,7 +25,7 @@
25
25
  </div>
26
26
  </div>
27
27
 
28
- <%= form_tag send(@Klass.to_s.underscore.pluralize + '_path', :update => @update_span,
28
+ <%= form_tag polymorphic_path(@Klass, :update => @update_span,
29
29
  :parent_class => @parent_class,
30
30
  :parent_id => @parent_id ),
31
31
  :multipart => true, :remote => true, :class => "edit_form" do -%>
@@ -56,7 +56,7 @@
56
56
  &nbsp;
57
57
  </div>
58
58
  <div class='small-11 column' >
59
- <%= link_to( send(@Klass.to_s.underscore.pluralize + '_path', :update => @update_span,
59
+ <%= link_to( polymorphic_path(@Klass, :update => @update_span,
60
60
  :parent_class => @parent_class,
61
61
  :parent_id => @parent_id,
62
62
  :ul_needed => true ),
@@ -1,8 +1,9 @@
1
1
  <% path_to_object = @object.class.to_s.underscore + '_path' %>
2
2
  <% css_class_id = "#{@object.class.name.underscore}_#{@object.id}_versions" -%>
3
+ <% entries = inline_forms_versions_for(@object) -%>
3
4
  <div class="row form_element_header associated_auto_header callout">
4
5
  <div class='medium-11 large-11 column' >
5
- <%= "Versions (#{@object.versions.length})" %>
6
+ <%= "Versions (#{entries.length})" %>
6
7
  </div>
7
8
  <div class='medium-1 large-1 column'>
8
9
  <%= close_versions_list_link(
@@ -29,20 +30,26 @@
29
30
  </div>
30
31
  </div>
31
32
  <div class="row <%= cycle('odd', 'even') %>">
32
- <% @object.versions.reverse.each do | version | %>
33
+ <% entries.reverse.each do |entry| %>
34
+ <% version = entry[:version] -%>
35
+ <% rich_text_name = entry[:rich_text_name] -%>
33
36
  <div class='small-12 column'>
34
37
  <div class="small-1 column">
35
- <%= link_to t('inline_forms.view.restore'),
36
- send('revert_' + @object.class.to_s.underscore + "_path",
37
- version,
38
- :update => "#{@object.class.name.underscore}_#{@object.id}"
39
- ),
40
- :remote => true,
41
- :method => :post
42
- %>
38
+ <% if entry[:kind] == :primary %>
39
+ <%= link_to t('inline_forms.view.restore'),
40
+ send('revert_' + @object.class.to_s.underscore + "_path",
41
+ version,
42
+ :update => "#{@object.class.name.underscore}_#{@object.id}"
43
+ ),
44
+ :remote => true,
45
+ :method => :post
46
+ %>
47
+ <% else %>
48
+ &nbsp;
49
+ <% end %>
43
50
  </div>
44
51
  <div class="small-1 column">
45
- <%= version.event -%>
52
+ <%= version.event -%><% if entry[:kind] == :rich_text %> <em>(rich text)</em><% end %>
46
53
  </div>
47
54
  <div class="small-2 column">
48
55
  <%= version.created_at -%>
@@ -56,9 +63,13 @@
56
63
  <% else %>
57
64
  <% version.changeset.each do |attribute, value| %>
58
65
  <% next if attribute == 'updated_at' %>
66
+ <% next if entry[:kind] == :rich_text && attribute == 'record_id' %>
67
+ <% next if entry[:kind] == :rich_text && attribute == 'record_type' %>
68
+ <% next if entry[:kind] == :rich_text && attribute == 'name' %>
69
+ <% display_attribute = entry[:kind] == :rich_text && attribute == 'body' ? rich_text_name : attribute -%>
59
70
  <table>
60
71
  <tr>
61
- <th colspan="2" class="text-center"><%= attribute %></th>
72
+ <th colspan="2" class="text-center"><%= display_attribute %></th>
62
73
  <th></th>
63
74
  </tr>
64
75
  <tr>
@@ -66,8 +77,13 @@
66
77
  <td>new value</td>
67
78
  </tr>
68
79
  <tr>
69
- <td><%= value[0] %></td>
70
- <td><%= value[1] %></td>
80
+ <% if entry[:kind] == :rich_text && attribute == 'body' %>
81
+ <td><%= raw value[0] %></td>
82
+ <td><%= raw value[1] %></td>
83
+ <% else %>
84
+ <td><%= value[0] %></td>
85
+ <td><%= value[1] %></td>
86
+ <% end %>
71
87
  </tr>
72
88
  </table>
73
89
  <% end %>
@@ -7,12 +7,14 @@
7
7
  <%= t('inline_forms.general.application_title') %> v<%= InlineForms::VERSION %>
8
8
  </title>
9
9
  <%= stylesheet_link_tag "application" %>
10
+ <%= stylesheet_link_tag "https://unpkg.com/trix@1.3.1/dist/trix.css" %>
10
11
  <%= csrf_meta_tags %>
11
12
  </head>
12
13
 
13
14
  <body>
14
15
  <%= yield %>
15
16
  <%= javascript_include_tag "application", 'data-turbolinks-track' => true %>
16
- <%= javascript_include_tag Ckeditor.cdn_url %>
17
+ <%= javascript_include_tag "https://unpkg.com/trix@1.3.1/dist/trix.js" %>
18
+ <%= javascript_include_tag Ckeditor.cdn_url if defined?(Ckeditor) %>
17
19
  </body>
18
20
  </html>
@@ -6,6 +6,7 @@
6
6
  <title><%= t('application_name') + " v" + InlineForms::VERSION -%></title>
7
7
  <%= stylesheet_link_tag "application" %>
8
8
  <%= stylesheet_link_tag "inline_forms/inline_forms" %>
9
+ <%= stylesheet_link_tag "https://unpkg.com/trix@1.3.1/dist/trix.css" %>
9
10
  <%= csrf_meta_tags %>
10
11
  </head>
11
12
 
@@ -16,6 +17,7 @@
16
17
  <%= yield %>
17
18
  </div>
18
19
  <%= javascript_include_tag 'inline_forms/inline_forms', 'data-turbolinks-track' => true %>
19
- <%= javascript_include_tag Ckeditor.cdn_url %>
20
+ <%= javascript_include_tag "https://unpkg.com/trix@1.3.1/dist/trix.js" %>
21
+ <%= javascript_include_tag Ckeditor.cdn_url if defined?(Ckeditor) %>
20
22
  </body>
21
23
  </html>
data/bin/inline_forms CHANGED
@@ -110,7 +110,7 @@ module InlineForms
110
110
 
111
111
  app_template_file = File.join(File.dirname(__FILE__), 'inline_forms_app_template.rb')
112
112
 
113
- if ! run("rails new #{app_name} -m #{app_template_file} --skip-bundle --skip-gemfile --skip-test-unit --skip-bootsnap")
113
+ if ! run("rails new #{app_name} -m #{app_template_file} --skip-bundle --skip-bootsnap --javascript=importmap")
114
114
  say "Rails could not create the app '#{app_name}', maybe because it is a reserved word...", :red # TODO ROYTJE MAKE ERROR MESSAGE MORE RELEVANT # Rails could not create the app 'MyApp', maybe because it is a reserved word..
115
115
  exit 1
116
116
  end
@@ -1,37 +1,49 @@
1
1
  GENERATOR_PATH = File.dirname(File.expand_path(__FILE__)) + '/../'
2
2
 
3
+ # Rails 7 dropped --skip-gemfile, so `rails new` always writes its own Gemfile.
4
+ # Remove it so our `create_file` below does not prompt for overwrite.
5
+ remove_file 'Gemfile' if File.exist?('Gemfile')
3
6
  create_file 'Gemfile', "# created by inline_forms #{ENV['inline_forms_version']} on #{Date.today}\n"
4
7
 
5
8
  add_source 'https://rubygems.org'
6
9
 
7
10
  gem 'cancancan'
8
- gem 'carrierwave'
9
- gem 'ckeditor', github: 'galetahub/ckeditor'
10
- gem 'coffee-rails'
11
+ gem 'carrierwave', '~> 3.1'
11
12
  gem 'devise-i18n', :git => 'https://github.com/acesuares/devise-i18n.git'
12
13
  gem 'devise'
13
14
  gem 'foundation-icons-sass-rails'
14
15
  gem 'foundation-rails', '~> 5.5'
15
16
  gem 'i18n-active_record', :git => 'https://github.com/acesuares/i18n-active_record.git'
16
- gem 'inline_forms', '~> 6.2'
17
+ gem 'inline_forms', path: "#{File.expand_path(GENERATOR_PATH)}"
17
18
  gem 'jquery-rails'
18
19
  gem 'jquery-timepicker-rails'
19
20
  gem 'jquery-ui-sass-rails'
20
21
  gem 'mini_magick'
21
22
  gem 'mysql2'
22
- gem 'paper_trail', git: 'https://github.com/acesuares/paper_trail.git'
23
- gem 'rails-i18n', :git => 'https://github.com/svenfuchs/rails-i18n.git' # since https://github.com/svenfuchs/rails-i18n/pull/794 we don't have to maintain 'https://github.com/acesuares/rails-i18n.git' anymore!
23
+ gem 'paper_trail', '~> 16.0'
24
+ gem 'rails-i18n', '~> 7.0'
24
25
  gem 'rails-jquery-autocomplete'
25
- gem 'rails', '6.1.3.1'
26
+ gem 'rails', '~> 7.0.0'
26
27
  gem 'rake'
27
28
  gem 'remotipart', '~> 1.0'
28
29
  gem 'rvm'
29
30
  gem 'sass-rails'
31
+ # Rails 7 no longer adds sprockets-rails to the default Gemfile; declare it
32
+ # explicitly because the gem's own assets (foundation, jquery, etc.) live in
33
+ # app/assets and rely on the Sprockets pipeline.
34
+ gem 'sprockets-rails'
35
+ # Rails 7 default JavaScript tooling: importmap-rails replaces Webpacker.
36
+ gem 'importmap-rails'
30
37
  gem 'tabs_on_rails', :git => 'https://github.com/acesuares/tabs_on_rails.git', :branch => 'update_remote_before_action'
31
38
  gem 'unicorn'
32
39
  gem 'validation_hints'
33
40
  gem 'will_paginate' #, git: 'https://github.com/acesuares/will_paginate.git'
34
41
 
42
+ gem_group :test do
43
+ # Rails 7 still expects Minitest 5; 6.x breaks the railties test runner.
44
+ gem 'minitest', '~> 5.25'
45
+ end
46
+
35
47
  gem_group :development do
36
48
  gem 'capistrano-bundler', require: false
37
49
  gem 'capistrano-rails', require: false
@@ -41,7 +53,8 @@ gem_group :development do
41
53
  gem 'rvm-capistrano', :require => false
42
54
  gem 'rvm1-capistrano3', require: false
43
55
  gem 'seed_dump', '~> 0.5.3'
44
- gem 'sqlite3'
56
+ # Rails 6.1 ActiveRecord's sqlite3 adapter requires sqlite3 ~> 1.4; 2.x activates first and breaks.
57
+ gem 'sqlite3', '~> 1.4'
45
58
  gem 'switch_user'
46
59
  gem 'thin'
47
60
  gem 'yaml_db'
@@ -66,6 +79,12 @@ if ENV['using_sqlite'] == 'true'
66
79
  pool: 5
67
80
  timeout: 5000
68
81
 
82
+ test:
83
+ adapter: sqlite3
84
+ database: db/test.sqlite3
85
+ pool: 5
86
+ timeout: 5000
87
+
69
88
  END_DATABASEYML
70
89
  else
71
90
  create_file "config/database.yml", <<-END_DATABASEYML.strip_heredoc
@@ -142,7 +161,7 @@ create_file "db/migrate/" +
142
161
  Time.now.utc.strftime("%Y%m%d%H%M%S") +
143
162
  "_" +
144
163
  "devise_create_users.rb", <<-DEVISE_MIGRATION.strip_heredoc
145
- class DeviseCreateUsers < ActiveRecord::Migration[5.0]
164
+ class DeviseCreateUsers < ActiveRecord::Migration[7.0]
146
165
 
147
166
  def change
148
167
  create_table(:users) do |t|
@@ -295,7 +314,7 @@ create_file "db/migrate/" +
295
314
  Time.now.utc.strftime("%Y%m%d%H%M%S") +
296
315
  "_" +
297
316
  "inline_forms_create_join_table_user_role.rb", <<-ROLES_MIGRATION.strip_heredoc
298
- class InlineFormsCreateJoinTableUserRole < ActiveRecord::Migration[5.0]
317
+ class InlineFormsCreateJoinTableUserRole < ActiveRecord::Migration[7.0]
299
318
  def self.up
300
319
  create_table :roles_users, :id => false, :force => true do |t|
301
320
  t.integer :role_id
@@ -321,24 +340,69 @@ say "- Add human_attribute_name in app/models/application_record.rb"
321
340
  remove_file 'app/models/application_record.rb' # the one that 'rails new' created
322
341
  copy_file File.join(GENERATOR_PATH, 'lib/generators/templates/application_record.rb'), "app/models/application_record.rb"
323
342
 
324
- say "- Install ckeditor..."
325
- generate "ckeditor:install --orm=active_record --backend=carrierwave"
326
-
327
- say "- Copy ckeditor/config.js to app/javascripts..."
328
- empty_directory "app/assets/javascripts/ckeditor"
329
- copy_file File.join(GENERATOR_PATH,'lib/generators/assets/javascripts/ckeditor/config.js'), "app/assets/javascripts/ckeditor/config.js"
330
-
331
- say "- Add ckeditor/config.js to precompile assets..."
332
- append_to_file 'config/initializers/assets.rb',
333
- 'Rails.application.config.assets.precompile += %w[ckeditor/config.js]'
343
+ say "- Install ActionText..."
344
+ run "bundle exec rails active_storage:install"
345
+ run "bundle exec rails action_text:install:migrations"
346
+ run "bundle install"
334
347
 
335
348
  say "- Paper_trail install..."
336
- generate "paper_trail:install --with-changes --with-mysql"
349
+ # Upstream paper_trail (>= 13) detects MySQL via the live ActiveRecord connection,
350
+ # so the migration's InnoDB options are added only when the dev DB is mysql.
351
+ # For mysql installs the user has been instructed above to create the development
352
+ # database before continuing; for sqlite the file is created on first connection.
353
+ generate "paper_trail:install --with-changes"
354
+ # paper_trail emits two migrations in one second; the next generator would reuse that timestamp.
355
+ sleep 1
356
+
357
+ say "- Track ActionText (rich_text) edits with PaperTrail..."
358
+ # `has_rich_text :foo` stores the body in the separate `action_text_rich_texts`
359
+ # table, not on the parent model, so `has_paper_trail` on the parent never
360
+ # sees rich_text edits. The standard fix (recommended by paper_trail's
361
+ # maintainer in https://stackoverflow.com/q/55544935) is to declare
362
+ # `has_paper_trail` directly on `ActionText::RichText`. We surface those
363
+ # versions in the parent's versions panel from `inline_forms_versions_for`.
364
+ #
365
+ # Note: PaperTrail >= 16 raises if `has_paper_trail` is called twice on the
366
+ # same model, so this initializer must be the only place it's added to
367
+ # `ActionText::RichText` in the generated app.
368
+ create_file 'config/initializers/rich_text_paper_trail.rb', <<-PT_RICH_TEXT.strip_heredoc
369
+ # Generated by inline_forms.
370
+ ActiveSupport.on_load(:action_text_rich_text) do
371
+ has_paper_trail
372
+ end
373
+ PT_RICH_TEXT
374
+
375
+ say "- Configure ActiveRecord YAML permitted classes for PaperTrail changesets..."
376
+ # PaperTrail's YAML serializer (>= 13) uses `YAML.safe_load` and reads its
377
+ # allow-list from `ActiveRecord.yaml_column_permitted_classes`. Rails 7's
378
+ # default is `[Symbol]`, so any update that touches `updated_at`
379
+ # (an `ActiveSupport::TimeWithZone`) raises `Psych::DisallowedClass` inside
380
+ # `version.changeset`; PaperTrail rescues that and returns `{}`, which is why
381
+ # the inline_forms versions list rendered every changeset as `empty`. Permit
382
+ # the classes PT actually emits so `version.changeset` round-trips.
383
+ create_file 'config/initializers/paper_trail_yaml_safe_load.rb', <<-PT_YAML.strip_heredoc
384
+ # Generated by inline_forms.
385
+ # See https://github.com/paper-trail-gem/paper_trail and
386
+ # ActiveRecord::Coders::YAMLColumn safe-loading rules.
387
+ Rails.application.config.active_record.yaml_column_permitted_classes ||= []
388
+ Rails.application.config.active_record.yaml_column_permitted_classes |= [
389
+ Symbol,
390
+ Date,
391
+ Time,
392
+ BigDecimal,
393
+ ActiveSupport::TimeWithZone,
394
+ ActiveSupport::TimeZone,
395
+ ActiveSupport::HashWithIndifferentAccess
396
+ ]
397
+ ActiveRecord.yaml_column_permitted_classes |= Rails.application.config.active_record.yaml_column_permitted_classes
398
+ PT_YAML
337
399
 
338
400
  # Create Translations
339
401
  say "- Generate models and tables and views for translations..." # TODO Translations need to be done in inline_forms, and then generate a yml file, perhaps
340
402
  generate "inline_forms", "InlineFormsLocale name:string inline_forms_translations:belongs_to _enabled:yes _presentation:\#{name}"
403
+ sleep 1 # unique migration timestamps per generator
341
404
  generate "inline_forms", "InlineFormsKey name:string inline_forms_translations:has_many inline_forms_translations:associated _enabled:yes _presentation:\#{name}"
405
+ sleep 1
342
406
  generate "inline_forms", "InlineFormsTranslation inline_forms_key:belongs_to inline_forms_locale:dropdown value:text interpolations:text is_proc:boolean _presentation:\#{value}"
343
407
  # TODO: fix text_area into text_area_without_ckeditor
344
408
  sleep 1 # to get unique migration number
@@ -346,7 +410,7 @@ create_file "db/migrate/" +
346
410
  Time.now.utc.strftime("%Y%m%d%H%M%S") +
347
411
  "_" +
348
412
  "inline_forms_create_view_for_translations.rb", <<-VIEW_MIGRATION.strip_heredoc
349
- class InlineFormsCreateViewForTranslations < ActiveRecord::Migration[5.0]
413
+ class InlineFormsCreateViewForTranslations < ActiveRecord::Migration[7.0]
350
414
  def self.up
351
415
  execute 'CREATE VIEW translations
352
416
  AS
@@ -554,18 +618,26 @@ git commit: " -a -m 'Initial Commit'"
554
618
  # example
555
619
  if ENV['install_example'] == 'true'
556
620
  say "\nInstalling example application..."
557
- run 'bundle exec rails g inline_forms Photo name:string caption:string image:image_field description:ckeditor apartment:belongs_to _presentation:\'#{name}\''
621
+ run 'bundle exec rails g inline_forms Photo name:string caption:string image:image_field description:rich_text apartment:belongs_to _presentation:\'#{name}\''
558
622
  run 'bundle exec rails generate uploader Image'
559
- run 'bundle exec rails g inline_forms Apartment name:string title:string description:ckeditor photos:has_many photos:associated _enabled:yes _presentation:\'#{name}\''
623
+ run 'bundle exec rails g inline_forms Apartment name:string title:string description:rich_text photos:has_many photos:associated _enabled:yes _presentation:\'#{name}\''
560
624
  run 'bundle exec rake db:migrate'
561
625
 
562
626
  remove_file 'public/index.html'
563
627
 
564
628
  route "root :to => 'apartments#index'"
565
629
 
566
- say "\nDone! Now point your browser to http://localhost:3000", :yellow
567
- say "\nPress ctlr-C to quit...", :yellow
568
- run 'bundle exec rails s'
630
+ say "- Adding example app regression tests (bundle exec rails test)..."
631
+ example_tests_root = File.join(GENERATOR_PATH, "lib/installer_templates/example_app_tests")
632
+ Dir.glob(File.join(example_tests_root, "**", "*.rb")).sort.each do |abs|
633
+ rel = abs.delete_prefix(example_tests_root + File::SEPARATOR).tr("\\", "/")
634
+ create_file rel, File.read(abs)
635
+ end
636
+
637
+ say "\nDone! Example app (Photo + Apartment) is ready.", :yellow
638
+ say " bundle exec rails test # example regression tests", :yellow
639
+ say " bundle exec rails s # then http://localhost:3000/apartments", :yellow
640
+ say " Log in: #{ENV["email"]} / #{ENV["password"]}", :yellow
569
641
  end
570
642
  # done!
571
643
  say "\nDone! Now make your tables with 'bundle exec rails g inline_forms ...", :yellow
@@ -0,0 +1,5 @@
1
+ # Keep this directory for checked-in prompt docs.
2
+ # Ignore local scratch files by default.
3
+ *
4
+ !.gitignore
5
+ !*.md
@@ -0,0 +1,32 @@
1
+ You are in the inline_forms gem repo at /home/code/inline_forms.
2
+
3
+ Goal:
4
+ Build the current gem, install it into /home/code/testInline, recreate MyApp from scratch using --example, and verify it with Rails tests.
5
+
6
+ Do all steps end-to-end without asking for confirmation unless a command fails.
7
+
8
+ Steps:
9
+ 1) In /home/code/inline_forms:
10
+ - Ensure latest code is used.
11
+ - Run: rvm use .
12
+ - Build gem: gem build inline_forms.gemspec
13
+ - Confirm the built file name/version (inline_forms-<version>.gem).
14
+
15
+ 2) In /home/code/testInline:
16
+ - Remove old app if present: /home/code/testInline/MyApp
17
+ - Run: rvm use .
18
+ - Install the freshly built gem from /home/code/inline_forms/inline_forms-<version>.gem
19
+
20
+ 3) Still in /home/code/testInline:
21
+ - Generate fresh example app:
22
+ inline_forms create MyApp -d sqlite --example
23
+
24
+ 4) In /home/code/testInline/MyApp:
25
+ - Run: rvm use .
26
+ - Run verification: bundle exec rails test
27
+
28
+ Output requirements:
29
+ - Briefly report each phase result (build, install, app generation, test run).
30
+ - Include exact commands run.
31
+ - Include test summary (runs/assertions/failures/errors/skips).
32
+ - If anything fails, stop at the failing step and include the exact error and the next corrective command you recommend.
data/inline_forms.gemspec CHANGED
@@ -23,7 +23,9 @@ Gem::Specification.new do |s|
23
23
  s.add_dependency('rvm')
24
24
  s.add_dependency('thor')
25
25
  s.add_dependency('validation_hints')
26
- s.add_dependency('rails', '6.1.3.1')
26
+ s.add_dependency('rails', '>= 7.0.0', '< 7.1')
27
27
  s.add_dependency('rails-i18n')
28
28
 
29
+ s.add_development_dependency("minitest", "~> 5.0")
30
+
29
31
  end