hot-glue 0.6.29 → 0.6.30

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2adecf8cc5b25919ee16219a6dbf4176a178a1a393adf6a79ae1370a9fe89a9
4
- data.tar.gz: 0e02cf776a658911f19bc65f057eb60b57cb04e54a783883e6eb17cc05c0a2fb
3
+ metadata.gz: 7eb77747230d52128ce322520c8c208c5e235cb27cca4042c99a0ce0e910382b
4
+ data.tar.gz: 9ba630157d1335f28acb15c7342f2d3489e63358ad38fd4d19185162fceb6895
5
5
  SHA512:
6
- metadata.gz: 7789fd5eae2defcc87512f2d10fb3e40c8c68c8ae33380ea072b80239b985edd4f3a1cb4593472fc468e084b4ff480c450ea6edc79384fa3a3013fede972aff6
7
- data.tar.gz: 0c5ed6e3d2478c86c6bfa08ed0b4e0306ff9160673c557cb02e633509ce5e93d636b4bd36c11e5d955de5443e5945d71c23caca424979dc9cc0f6377e88b418a
6
+ metadata.gz: 990d8138a2916b7599ea831b8c2d09d70b5df653a0ec8b2f88632eae696c21ecd24406ec1d0b8ea180ffdc2fe1401a2030672d6e7c5695693e2c86d1222a01e5
7
+ data.tar.gz: c396428e8d84b06fe05483add1a9d89ea7149e303efef49d14cccafe3ce25312440b8620db4a5d79fe0bd9e4876b71e98bbac895a540a24cdd7f1b752afb2711
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- hot-glue (0.6.28)
4
+ hot-glue (0.6.29)
5
5
  ffaker (~> 2.16)
6
6
  rails (> 5.1)
7
7
 
data/README.md CHANGED
@@ -558,22 +558,24 @@ The child object is named `Rule` but it can belong to a Blast or an Agent. (Agen
558
558
 
559
559
  We build the blast & agent controllers like so:
560
560
 
561
- bin/rails generate hot_glue:scaffold Blast --downnest='blast_rules(rules)'
562
- bin/rails generate hot_glue:scaffold Agent --downnest='agent_rules(rules)'
561
+
562
+ `bin/rails generate hot_glue:scaffold Blast --downnest='blast_rules(rules)'`
563
+
564
+ `bin/rails generate hot_glue:scaffold Agent --downnest='agent_rules(rules)'`
563
565
 
564
566
  Notice that the relationship name is `rules` (not blast_rules), so what goes before the parenthesis is the controller name (with prefix)
565
567
  What goes inside the controller name is the real relationship name.
566
568
 
567
569
  For the children, we can't build one controller for the Rule, instead we build one for the `AgentRules` and another for the `BlastRules`
568
570
 
569
- bin/rails generate hot_glue:scaffold Rule --nested='blast(ruleable)' --controller-prefix='Blast'
570
- bin/rails generate hot_glue:scaffold Rule --nested='agent(ruleable)' --controller-prefix='Agent'
571
+ `bin/rails generate hot_glue:scaffold Rule --nested='blast(ruleable)' --controller-prefix='Blast'`
572
+ `bin/rails generate hot_glue:scaffold Rule --nested='agent(ruleable)' --controller-prefix='Agent'`
571
573
 
572
574
  (I realize building one child controller for each type of polymorph is tedius, but this is the best solution I could come up with.)
573
575
 
574
576
  As these are children, what goes into the `--netsed` setting inside the parentheses is the polymorphic name specified by `as:` when declaring the `belongs_to`
575
577
 
576
- routes.rb
578
+ config/routes.rb
577
579
 
578
580
  ```
579
581
  resources :agents do
@@ -585,6 +587,22 @@ routes.rb
585
587
  end
586
588
  ```
587
589
 
590
+ Outside a polymorphic relationship, you sometimes have children with `belongs_to` that uses a custom name instead of the name of the class (using class_name on the belongs to)
591
+
592
+ Imagine a `followings` table with two foreign keys: follower_id and follows_id (both pointing to a BskyUser)
593
+
594
+
595
+ `belongs_to :follower, class_name: "BskyUser", foreign_key: :follower_id`
596
+ `belongs_to :follows, class_name: "BskyUser", foreign_key: :follows_id`
597
+
598
+
599
+ Here, specify nested using square braces for the non-standard parent name
600
+
601
+ `--nested='bsky_users[follower]'` and `--nested='bsky_users[follows]'`
602
+
603
+
604
+
605
+
588
606
  ### `--stacked-downnesting`
589
607
 
590
608
  This puts the downnested portals on top of one another (stacked top to bottom) instead of side-by-side (left to right). This is useful if you have a lot of downnested portals and you want to keep the page from getting too wide.
@@ -2161,8 +2179,30 @@ This means that to find users within the search, the essential piece of informat
2161
2179
  end
2162
2180
  ```
2163
2181
 
2182
+ If you want your typeahead to accept an input for a non-matched field, you need to use a factory (see `--factory-creation`)
2183
+
2184
+ Here, we assume that Authors are nested within a library (an arbitrary abstraction to demonstrate a typeahead at a nested route)
2185
+
2186
+ ```
2187
+ factory = AuthorsFactory.new(
2188
+ library: library,
2189
+ query: params[:authors_query],
2190
+ author_params: modified_params)
2191
+ ```
2192
+
2193
+ Your authors factory will need to check the params for `author_params[:author_id].empty?`
2164
2194
 
2165
2195
 
2196
+ When the factory is passed an empty string here, it is from a non-matched lookup. You will either lookup the author_id if provided, or create a new one if not
2197
+ ```
2198
+ if !author_params[:author_id].empty?
2199
+ author = Author.find(author_params[:author_id])
2200
+ else
2201
+ author = Target.find_or_create_by!(library: library, name: query)
2202
+ end
2203
+ ```
2204
+ Notice this is creating a new author by the `name` field, which should be same field you are searching by in the typeahead.
2205
+
2166
2206
  --
2167
2207
 
2168
2208
 
@@ -2244,13 +2284,19 @@ These automatic pickups for partials are detected at build time. This means that
2244
2284
 
2245
2285
  # VERSION HISTORY
2246
2286
 
2247
- #### 2025-10-11 - v0.6.39
2287
+ #### 2025-10-19 - v0.6.30
2288
+ - fixes references from search typeaheads to a typeahead controller which is nested
2289
+ - `--nested` can now take square braces if the relationship from child to parent (belongs_to) uses a non-standard association name; @downnest_object fix for data array; changes to object_scope to accomodate new paradigm
2290
+
2291
+
2292
+
2293
+ #### 2025-10-11 - v0.6.29
2248
2294
 
2249
2295
  • When specifying a alt lookup in non-Gd mode, we treat this a security concern because alt lookups can get any related record from the database; if you use a factory when creating your object, you can pass the lookup to the factory and scope your lookup in there; fix to not raise exception when specified an alt lookup in non-Gd mode if you are also using a factory
2250
2296
 
2251
2297
  • Attachments now have a graceful fail if the attachment is invariable (cannot be made into a thumbnail), and so there is no thumbnail to display. Instead, a small box with the file type ("pdf" or "msword") is shown in place where the thumbnail would display
2252
2298
 
2253
- • Adds a 'tripple' implementation for newer pagination gems: will_paginate and pagy. HG will auto detect which pagination gem you have in your Gemfile, and pick ONE of the three based on this preference order: Pagy over will_paginate; will_paginate over Kaminari, no pagination if none of the three are installed.
2299
+ • Adds a 'triple' implementation for newer pagination gems: will_paginate and pagy. HG will auto detect which pagination gem you have in your Gemfile, and pick ONE of the three based on this preference order: Pagy over will_paginate; will_paginate over Kaminari, no pagination if none of the three are installed.
2254
2300
 
2255
2301
  Kaminari is barely workable with newer Rails and seems somewhat abandoned; will_paginate is officially in maintenance mode, so Pagy is the way to go. I have implemented all three for the widest legacy support. On my Rails Cookbook pages, I have replaced Kaminari with Pagy.
2256
2302
 
@@ -204,7 +204,7 @@ class AssociationField < Field
204
204
  assoc_name = name.to_s.gsub("_id","")
205
205
  assoc = eval("#{class_name}.reflect_on_association(:#{assoc_name})")
206
206
  if modify_as && modify_as[:typeahead]
207
- search_url = "#{namespace ? namespace + "_" : ""}#{assoc.class_name.downcase.pluralize}_typeahead_index_url"
207
+ search_url = "#{namespace ? namespace + "_" : ""}#{modify_as[:nested] ? modify_as[:nested][0] + "_" : ""}#{assoc.class_name.downcase.pluralize}_typeahead_index_url"
208
208
 
209
209
  # \"q[0][#{name}_search]\"
210
210
  # @q['0']['#{name}_search']
@@ -39,7 +39,6 @@ class LayoutStrategy::Bootstrap < LayoutStrategy::Base
39
39
  end
40
40
 
41
41
  def downnest_portal_column_width(downnest)
42
-
43
42
  "col-sm-#{ builder.layout_object[:portals][downnest][:size] }"
44
43
  end
45
44
 
@@ -456,11 +456,10 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
456
456
 
457
457
  child_name.gsub!("+","")
458
458
 
459
-
460
- @downnest_object[child] = {
459
+ @downnest_object[child_name] = {
461
460
  name: child_name,
462
461
  extra_size: extra_size,
463
- polymorph_as: polymorph_as
462
+ polymorph_as: polymorph_as,
464
463
  }
465
464
  end
466
465
  end
@@ -512,17 +511,27 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
512
511
 
513
512
  if !@nested.nil?
514
513
  @nested_set = @nested.split("/").collect { |arg|
515
- if arg.include?("(")
514
+ if arg.include?("[") && arg.include?("(")
515
+ arg =~ /(.*)\((.*)\)\[(.*)\]/
516
+ singular, polymorph_as, parent_name = $1, $2, $3
517
+
518
+ elsif arg.include?("(")
516
519
  arg =~ /(.*)\((.*)\)/
517
520
  singular, polymorph_as = $1, $2
521
+ parent_name = singular
522
+ elsif arg.include?("[")
523
+ arg =~ /(.*)\[(.*)\]/
524
+ singular, parent_name = $1, $2
518
525
  else
519
526
  singular = arg
527
+ parent_name = singular
520
528
  end
521
529
 
522
530
  {
523
531
  singular: singular,
524
532
  plural: singular.pluralize,
525
- polymorph_as: polymorph_as
533
+ polymorph_as: polymorph_as,
534
+ parent_name: parent_name
526
535
  }
527
536
  }
528
537
  puts "NESTING: #{@nested_set}"
@@ -1426,17 +1435,34 @@ class HotGlue::ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
1426
1435
  end
1427
1436
 
1428
1437
  def object_scope
1438
+ if @nested_set.any? && @nested_set.last[:parent_name]
1439
+ last_parent = @nested_set.last[:parent_name]
1440
+ foreign_key = eval("#{singular_class}.reflect_on_association(:#{last_parent})").foreign_key
1441
+ association = eval(singular_class).reflect_on_association(@nested_set.last[:parent_name].to_sym)
1442
+ .klass.reflect_on_all_associations(:has_many)
1443
+ .to_a.find{|x|
1444
+
1445
+ if x.source_reflection
1446
+ x.foreign_key == foreign_key
1447
+
1448
+ # raise "#{singular_class} class declaration is missing source reflection for the `has_many :#{x.name}` association"
1449
+ end
1450
+ }.plural_name
1451
+ else
1452
+ association = plural
1453
+ end
1454
+
1429
1455
  if @auth && !@god
1430
1456
  if @nested_set.none?
1431
- @auth + ".#{plural}"
1457
+ @auth + ".#{association}"
1432
1458
  else
1433
- "@" + @nested_set.last[:singular] + ".#{plural}"
1459
+ "@" + @nested_set.last[:singular] + ".#{association}"
1434
1460
  end
1435
1461
  else
1436
1462
  if @nested_set.none?
1437
1463
  @singular_class
1438
1464
  else
1439
- "@" + @nested_set.last[:singular] + ".#{plural}"
1465
+ "@" + @nested_set.last[:singular] + ".#{association}"
1440
1466
  end
1441
1467
  end
1442
1468
  end
@@ -24,15 +24,15 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
24
24
  before_action :<%= arg[:singular] %><%= ", if: -> { params.include?(:#{arg[:singular]}_id) }" if arg[:optional] %><% } %><% end %>
25
25
  before_action :load_<%= singular_name %>, only: %i[<%= "show edit update" unless @no_edit %> <%= "destroy" unless @no_delete %>]
26
26
  after_action -> { flash.discard }, if: -> { request.format.symbol == :turbo_stream }<% if @nested_set.any? %>
27
- def <%= @nested_set[0][:singular] %><% if @god
27
+
28
+ def <%= @nested_set[0][:singular] %><% if @god
28
29
  next_object = nil
29
30
  collect_objects = @nested_set.reverse.collect {|x|
30
- if eval("#{next_object || class_name}.reflect_on_association(:#{x[:singular]})").nil? #&& eval("! #{next_object || class_name}.instance_methods.include?(:#{x[:singular]})")
31
- raise "***** Unable to find the association `#{x[:singular]}` on the class #{next_object || class_name} ..... you probably want to add `belongs_to :#{x[:singular]}` to the #{next_object || class_name} object?"
32
- end
33
- # if eval("#{next_object || class_name}.reflect_on_association(:#{x[:singular]})")
34
- next_object = eval("#{next_object || class_name}.reflect_on_association(:#{x[:singular]})").class_name
31
+ assoc_name = x[:parent_name] || x[:singular]
32
+ # if eval("#{next_object || class_name}.reflect_on_association(:#{assoc_name})").nil?
33
+ # raise "***** Unable to find the association `#{assoc_name}` on the class #{next_object || class_name} ..... you probably want to add `belongs_to :#{assoc_name}` to the #{next_object || class_name} object?"
35
34
  # end
35
+ next_object = eval("#{next_object || class_name}.reflect_on_association(:#{assoc_name})").class_name
36
36
  }
37
37
  root_object = collect_objects.last
38
38
  else
@@ -42,6 +42,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
42
42
  root_object = @auth + "." + @nested_set[0][:plural]
43
43
  end
44
44
  end
45
+
45
46
  %><% if !@god && @nested_set[0][:singular] == @auth_identifier %>
46
47
  @<%= @nested_set[0][:singular] %> ||= <%= root_object %>
47
48
  <% else %>
@@ -63,7 +64,7 @@ class <%= controller_class_name %> < <%= controller_descends_from %>
63
64
  def load_<%= singular_name %>
64
65
  <% if @nested_set[0] && @nested_set[0][:optional] %>if params.include?(:<%= @nested_set.last[:singular] %>_id)
65
66
  @<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])
66
- else <% end %>@<%= singular_name %> = <%= object_scope %>.find(params[:id])<% if @nested_set[0] && @nested_set[0][:optional] %>
67
+ else <% end %>@<%= singular_name %> = <%= object_scope.gsub("@",'') %>.find(params[:id])<% if @nested_set[0] && @nested_set[0][:optional] %>
67
68
  end<% end %>
68
69
  end
69
70
  <% else %>
@@ -1,5 +1,5 @@
1
1
  module HotGlue
2
2
  class Version
3
- CURRENT = '0.6.29'
3
+ CURRENT = '0.6.30'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hot-glue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.29
4
+ version: 0.6.30
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason Fleetwood-Boldt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-11 00:00:00.000000000 Z
11
+ date: 2025-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails