recourse 7.11.2 → 7.12.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/app/controllers/concerns/recourse/resource_resolution.rb +1 -1
- data/lib/recourse/helpers/resources.rb +2 -2
- data/lib/recourse/icons.rb +1 -1
- data/lib/recourse/routes/nested.rb +1 -1
- data/lib/recourse/titles.rb +1 -1
- data/lib/recourse/version.rb +1 -1
- data/lib/recourse.rb +48 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9e4b4229005fd88e1617e55a5f4760da0ebb2d7b897eabd730adeac07c7eb61d
|
|
4
|
+
data.tar.gz: b84e0db179300948a05e77e9bbdbdcbaad8ef1ee794632f42abeec752b3395ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2aa90f2ea92f2370ac39c64f0351518785bf3cb3233e7fab52e61cae83d8c90df80362a8c8267d451e8869b5e6da3cf22b9bb38b59c0510d7cc7958355da07e2
|
|
7
|
+
data.tar.gz: b0c47758910fe5c03c28084afa668adec4d6a07c399894f05ea0a7fbf57983c2988a84f72fed6a2ea84cb8a49c0730f9a894240e3ddfeb85f8a1f256b9081e2e
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ For more information about changelogs, check [Keep a Changelog](http://keepachan
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## 7.12.0 - 2026-10-02
|
|
11
|
+
|
|
12
|
+
* [FEATURE] A route drawn in a module lists the model kept in that module
|
|
13
|
+
|
|
14
|
+
`scope module: :admin { recourses :users }` lists an `Admin::User`, and so does a page
|
|
15
|
+
nested under a post, `admin/posts/users`. Only an Active Record model in the module counts;
|
|
16
|
+
where there is none, the route lists the top-level class of its last word, as before, so
|
|
17
|
+
`admin/comments` still lists a `Comment`. A host keeping models in a module will want
|
|
18
|
+
`def self.use_relative_model_naming? = true` on it, so their routes and params say `user`
|
|
19
|
+
rather than `admin_user`.
|
|
20
|
+
|
|
10
21
|
## 7.11.2 - 2026-09-26
|
|
11
22
|
|
|
12
23
|
* [FIX] The count in a tab is delimited
|
|
@@ -78,7 +78,7 @@ module Recourse
|
|
|
78
78
|
# to match it. Private, the way `recourse_relation` beside it is: naming a model
|
|
79
79
|
# adds no action.
|
|
80
80
|
def recourse_model
|
|
81
|
-
Recourse.model
|
|
81
|
+
Recourse.model controller_path
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
# What the page calls one of its rows: the model's own word, or the route's for a
|
|
@@ -15,7 +15,7 @@ module Recourse
|
|
|
15
15
|
def resources_name
|
|
16
16
|
return controller.controller_name.humanize if blob_resource?
|
|
17
17
|
|
|
18
|
-
Recourse.known_title controller.
|
|
18
|
+
Recourse.known_title controller.controller_path
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
# Singular, lowercase name of the resource, e.g. 'contact' — and 'photo' on a page
|
|
@@ -72,7 +72,7 @@ module Recourse
|
|
|
72
72
|
# Resolved by the controller, which is the one that knows whether the name is a
|
|
73
73
|
# model of this app's, something a record has attached, or a model a host named.
|
|
74
74
|
def resource_model
|
|
75
|
-
controller_assign('recourse_model') || Recourse.model(controller.
|
|
75
|
+
controller_assign('recourse_model') || Recourse.model(controller.controller_path)
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|
data/lib/recourse/icons.rb
CHANGED
|
@@ -8,7 +8,7 @@ module Recourse
|
|
|
8
8
|
# `Message` may be a host's own class for gathering rows rather than a table of them,
|
|
9
9
|
# and asking it would raise rather than draw nothing.
|
|
10
10
|
def self.known_icon(name)
|
|
11
|
-
model = name
|
|
11
|
+
model = model? name
|
|
12
12
|
|
|
13
13
|
known_model_icon model if model.respond_to? :recourse_icon
|
|
14
14
|
end
|
|
@@ -25,7 +25,7 @@ module Recourse
|
|
|
25
25
|
# `/placeholders/:placeholder_id/bookmark`, where nothing linked to it and
|
|
26
26
|
# anything reaching it raised. Asked of the constant rather than the class:
|
|
27
27
|
# loading a model while the routes draw is what Rails 8.2 warns about.
|
|
28
|
-
def addressable_rows? =
|
|
28
|
+
def addressable_rows? = Recourse.model_defined? declared_path(parent_resource.name)
|
|
29
29
|
|
|
30
30
|
# The place a row of a positioned table holds, at `/teams/5/position`. Recorded
|
|
31
31
|
# nowhere, for the reason the bookmark gives: a tab and a bare-action button both
|
data/lib/recourse/titles.rb
CHANGED
|
@@ -33,7 +33,7 @@ module Recourse
|
|
|
33
33
|
# than a table of them, and asking it would raise rather than read.
|
|
34
34
|
def known_title(name)
|
|
35
35
|
segment = name.to_s.split('/').last
|
|
36
|
-
model =
|
|
36
|
+
model = model? name
|
|
37
37
|
|
|
38
38
|
model.respond_to?(:model_name) ? model_title(model) : segment.humanize
|
|
39
39
|
end
|
data/lib/recourse/version.rb
CHANGED
data/lib/recourse.rb
CHANGED
|
@@ -71,11 +71,58 @@ module Recourse
|
|
|
71
71
|
# action is a verb — `recourse :sweep, only: :create` — and the gem labels its button
|
|
72
72
|
# from the path alone, so whether a name has a model behind it has to be a question
|
|
73
73
|
# and not an accusation.
|
|
74
|
-
def self.model?(name) = model_name(name).safe_constantize
|
|
74
|
+
def self.model?(name) = namespaced_model(name) || model_name(name).safe_constantize
|
|
75
75
|
|
|
76
76
|
# A namespaced resource is `admin/sources`, and the model it lists is a Source.
|
|
77
77
|
def self.model_name(name) = name.to_s.split('/').last.classify
|
|
78
78
|
|
|
79
|
+
# Whether a model answers the name, asked of the constants rather than the classes:
|
|
80
|
+
# the routes ask while they draw, and loading a model then is what Rails 8.2 warns
|
|
81
|
+
# about.
|
|
82
|
+
def self.model_defined?(name)
|
|
83
|
+
namespaced_names(name).any? { |namespaced| constant namespaced, load: false } ||
|
|
84
|
+
Object.const_defined?(model_name(name))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# A model the app keeps in the route's own module, where there is one: `admin/users`
|
|
88
|
+
# lists an Admin::User, and so does `admin/posts/users`, nested under a post.
|
|
89
|
+
# Only an Active Record model counts, so a concern or a host's own class that shares
|
|
90
|
+
# the name never takes a page over; and where there is none, `admin/comments` lists a
|
|
91
|
+
# Comment as it always has.
|
|
92
|
+
private_class_method def self.namespaced_model(name)
|
|
93
|
+
namespaced_names(name).each do |namespaced|
|
|
94
|
+
model = constant namespaced
|
|
95
|
+
return model if model.is_a?(Class) && model < ActiveRecord::Base
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
nil
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# The names a model in the route's modules goes by, innermost module first. The
|
|
102
|
+
# segment a nested route adds for its parent is a module no model lives in, so the
|
|
103
|
+
# module around it is asked next.
|
|
104
|
+
private_class_method def self.namespaced_names(name)
|
|
105
|
+
*modules, last = name.to_s.split '/'
|
|
106
|
+
modules.size.downto(1).map { |depth| [*modules[0, depth], last].join('/').classify }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# The constant a name gives, looked up one module at a time and never through Object:
|
|
110
|
+
# `safe_constantize` answers `Admin::Comment` with the top-level Comment, since a module
|
|
111
|
+
# looks its constants up there too. `load: false` stops short of the last one,
|
|
112
|
+
# answering only whether it is there.
|
|
113
|
+
private_class_method def self.constant(name, load: true)
|
|
114
|
+
*modules, last = name.split '::'
|
|
115
|
+
scope = modules.inject Object do |outer, part|
|
|
116
|
+
break unless outer.const_defined? part, false
|
|
117
|
+
|
|
118
|
+
outer.const_get part, false
|
|
119
|
+
end
|
|
120
|
+
return unless scope.is_a? Module
|
|
121
|
+
return unless scope.const_defined? last, false
|
|
122
|
+
|
|
123
|
+
load ? scope.const_get(last, false) : true
|
|
124
|
+
end
|
|
125
|
+
|
|
79
126
|
# Raised for every failure the gem reports, so hosts can rescue one type.
|
|
80
127
|
class Error < StandardError; end
|
|
81
128
|
end
|