crudable-rails 1.5.1 → 1.5.2
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/README.md +1 -1
- data/Rakefile +4 -0
- data/lib/crudable/rails/base.rb +26 -12
- data/lib/crudable/rails/nestable.rb +40 -4
- data/lib/crudable/rails/version.rb +1 -1
- data/lib/generators/crudable/templates/crudable_controller.rb.tt +9 -7
- data/lib/tasks/release.rake +59 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fc3416b37cdcba0d62e5da5cc65373ffe498e077c209ab305303dbdd89942a42
|
|
4
|
+
data.tar.gz: e847455e16084ef8fa1610718f2aec087c45463a31770f88dd847c18c6358c61
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2d6abc3f5a289011d558a213bef542f380c31c5efedf8359dbceecb6f63d543f3ec53c0a294d68828d424ed9b234dc162f73f07de188bd533e045a31063f47f3
|
|
7
|
+
data.tar.gz: 49906b171b7f358709f59553cf0fd10677e0b4b90d379bd7c99a07bad1d4ab456e79573027ba50547abb2ac743df4b89fc1ed1b56a8c11c26babf2db847b1ad5
|
data/README.md
CHANGED
|
@@ -231,7 +231,7 @@ The following private methods are available for use in your controllers:
|
|
|
231
231
|
|
|
232
232
|
### `after_create_redirect_path`
|
|
233
233
|
|
|
234
|
-
This method should return the path to redirect to after a successful create. By default this will redirect to the namespaced
|
|
234
|
+
This method should return the path to redirect to after a successful create. By default this will redirect to the namespaced member (show) path of the resource being created, including any nest parents — the same shape as `after_update_redirect_path`.
|
|
235
235
|
|
|
236
236
|
### `after_create_notice`
|
|
237
237
|
|
data/Rakefile
CHANGED
data/lib/crudable/rails/base.rb
CHANGED
|
@@ -122,7 +122,9 @@ module Crudable
|
|
|
122
122
|
resource = friendly_finders? ? resource_class.friendly : resource_class
|
|
123
123
|
instance = find_instance(resource)
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
# url_for keeps the current action/path parents and only swaps the finder param
|
|
126
|
+
# (e.g. numeric id → slug on edit stays on edit, not show).
|
|
127
|
+
return redirect_to url_for(finder_param => instance.to_param), status: :moved_permanently if should_redirect?(instance)
|
|
126
128
|
|
|
127
129
|
instance_variable_set("@#{resource_var_name}", instance)
|
|
128
130
|
rescue ActiveRecord::RecordNotFound
|
|
@@ -155,7 +157,27 @@ module Crudable
|
|
|
155
157
|
end
|
|
156
158
|
|
|
157
159
|
def should_redirect?(instance)
|
|
158
|
-
friendly_finders? &&
|
|
160
|
+
friendly_finders? && params[finder_param].to_s != instance.to_param.to_s
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Polymorphic args for a member path, including namespace and nest parents.
|
|
164
|
+
# e.g. [:admin, account, product] → admin_account_product_path
|
|
165
|
+
def resource_member_path_args(instance = nil)
|
|
166
|
+
instance ||= instance_variable_get("@#{resource_var_name}")
|
|
167
|
+
resource_namespace + resource_path_parents + [instance]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# Loaded path parents in route order (supports multi-level nesting when Nestable
|
|
171
|
+
# has set each parent ivar, including intermediate ones).
|
|
172
|
+
def resource_path_parents
|
|
173
|
+
return [] unless respond_to?(:parent_present?, true) && parent_present?
|
|
174
|
+
return [] unless respond_to?(:parent_id_param_keys, true)
|
|
175
|
+
|
|
176
|
+
parent_id_param_keys.map(&:to_s).filter_map do |key|
|
|
177
|
+
next unless key.end_with?('_id')
|
|
178
|
+
|
|
179
|
+
instance_variable_get("@#{key.delete_suffix('_id')}")
|
|
180
|
+
end
|
|
159
181
|
end
|
|
160
182
|
|
|
161
183
|
def singleton?
|
|
@@ -222,15 +244,7 @@ module Crudable
|
|
|
222
244
|
end
|
|
223
245
|
|
|
224
246
|
def after_create_redirect_path
|
|
225
|
-
|
|
226
|
-
parent = instance_variable_get("@#{parent_var_name}")
|
|
227
|
-
resource_namespace + [parent, plural_resource_var_name.to_sym]
|
|
228
|
-
else
|
|
229
|
-
resource_namespace + [plural_resource_var_name.to_sym]
|
|
230
|
-
end
|
|
231
|
-
rescue NoMethodError
|
|
232
|
-
# Fallback if parent_present? or parent_var_name methods aren't available
|
|
233
|
-
resource_namespace + [plural_resource_var_name.to_sym]
|
|
247
|
+
resource_member_path_args
|
|
234
248
|
end
|
|
235
249
|
|
|
236
250
|
def after_create_notice
|
|
@@ -238,7 +252,7 @@ module Crudable
|
|
|
238
252
|
end
|
|
239
253
|
|
|
240
254
|
def after_update_redirect_path
|
|
241
|
-
|
|
255
|
+
resource_member_path_args
|
|
242
256
|
end
|
|
243
257
|
|
|
244
258
|
def after_update_notice
|
|
@@ -13,10 +13,7 @@ module Crudable
|
|
|
13
13
|
def find_parent
|
|
14
14
|
return unless parent_present?
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
parent_scope = parent_class.friendly if parent_friendly_finders?
|
|
18
|
-
instance_variable_set("@#{parent_var_name}", parent_scope.find(params[parent_id_param]))
|
|
19
|
-
self.class.send(:decorates_assigned, parent_var_name.to_sym) if defined?(Draper)
|
|
16
|
+
load_path_parents
|
|
20
17
|
rescue ActiveRecord::RecordNotFound => e
|
|
21
18
|
# Only catch and render 404 if we're in a request context
|
|
22
19
|
# Check if we have a request object (indicates we're in a request context)
|
|
@@ -26,6 +23,45 @@ module Crudable
|
|
|
26
23
|
nil # Explicitly stop execution to prevent further action execution
|
|
27
24
|
end
|
|
28
25
|
|
|
26
|
+
# Loads every `*_id` path parent (shallow → deep) so multi-level nested routes
|
|
27
|
+
# can build polymorphic member paths that include the full ancestor chain.
|
|
28
|
+
# Scoping still uses the deepest parent via parent_id_param / parent_var_name.
|
|
29
|
+
def load_path_parents
|
|
30
|
+
parent_id_param_keys.map(&:to_s).grep(/\A(.+)_id\z/).each do |key|
|
|
31
|
+
load_path_parent(key)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def load_path_parent(key)
|
|
36
|
+
var_name = key.sub(/_id\z/, '')
|
|
37
|
+
return if instance_variable_get("@#{var_name}").present?
|
|
38
|
+
|
|
39
|
+
klass = parent_class_for(key)
|
|
40
|
+
scope = parent_find_scope_for(klass, key)
|
|
41
|
+
instance_variable_set("@#{var_name}", scope.find(params[key]))
|
|
42
|
+
self.class.send(:decorates_assigned, var_name.to_sym) if defined?(Draper)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Resolve the model class for a path parent param.
|
|
46
|
+
# Deepest parent uses #parent_class so controllers can override for namespaced models
|
|
47
|
+
# (e.g. Admin::Client). Override this for non-default intermediate parents.
|
|
48
|
+
def parent_class_for(key)
|
|
49
|
+
if key.to_s == parent_id_param.to_s
|
|
50
|
+
parent_class
|
|
51
|
+
else
|
|
52
|
+
key.to_s.sub(/_id\z/, '').classify.constantize
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def parent_find_scope_for(klass, key)
|
|
57
|
+
use_friendly = if key.to_s == parent_id_param.to_s
|
|
58
|
+
parent_friendly_finders?
|
|
59
|
+
else
|
|
60
|
+
defined?(FriendlyId) && klass.respond_to?(:friendly) && friendly_finders?
|
|
61
|
+
end
|
|
62
|
+
use_friendly ? klass.friendly : klass
|
|
63
|
+
end
|
|
64
|
+
|
|
29
65
|
def parent_id_param
|
|
30
66
|
return nil unless use_parent_as_scope?
|
|
31
67
|
|
|
@@ -124,15 +124,13 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
124
124
|
# end
|
|
125
125
|
#
|
|
126
126
|
# # Customize success redirects/flash messages.
|
|
127
|
+
# # Defaults redirect create/update to the member path (including nest parents).
|
|
127
128
|
# def after_create_redirect_path
|
|
128
|
-
# if
|
|
129
|
-
#
|
|
130
|
-
# resource_namespace + [parent, :<%= plural_table_name %>]
|
|
129
|
+
# if parent_present?
|
|
130
|
+
# resource_namespace + [instance_variable_get("@#{parent_var_name}"), @<%= singular_table_name %>]
|
|
131
131
|
# else
|
|
132
|
-
# resource_namespace + [
|
|
132
|
+
# resource_namespace + [@<%= singular_table_name %>]
|
|
133
133
|
# end
|
|
134
|
-
# rescue NoMethodError
|
|
135
|
-
# resource_namespace + [:<%= plural_table_name %>]
|
|
136
134
|
# end
|
|
137
135
|
#
|
|
138
136
|
# def after_create_notice
|
|
@@ -140,7 +138,11 @@ class <%= controller_class_name %>Controller < ApplicationController
|
|
|
140
138
|
# end
|
|
141
139
|
#
|
|
142
140
|
# def after_update_redirect_path
|
|
143
|
-
#
|
|
141
|
+
# if parent_present?
|
|
142
|
+
# resource_namespace + [instance_variable_get("@#{parent_var_name}"), @<%= singular_table_name %>]
|
|
143
|
+
# else
|
|
144
|
+
# resource_namespace + [@<%= singular_table_name %>]
|
|
145
|
+
# end
|
|
144
146
|
# end
|
|
145
147
|
#
|
|
146
148
|
# def after_update_notice
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
namespace :release do
|
|
4
|
+
desc 'Fail if any lib/ file is not world-readable (run before gem build)'
|
|
5
|
+
task :check do
|
|
6
|
+
root = File.expand_path('../..', __dir__)
|
|
7
|
+
|
|
8
|
+
non_readable = Dir.chdir(root) do
|
|
9
|
+
`find lib -type f ! -perm -004`.strip.split("\n").reject(&:empty?)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
if non_readable.any?
|
|
13
|
+
warn 'The following files under lib/ are not world-readable (need at least o+r):'
|
|
14
|
+
non_readable.each { |path| warn " #{path}" }
|
|
15
|
+
abort 'release:check failed'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
puts 'release:check passed (all lib/ files are world-readable)'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
desc 'Verify a built .gem has world-readable lib/ files (default: newest pkg/crudable-rails-*.gem)'
|
|
22
|
+
task :verify_gem, [:gem_path] do |_task, args|
|
|
23
|
+
root = File.expand_path('../..', __dir__)
|
|
24
|
+
gem_path = args[:gem_path]
|
|
25
|
+
if gem_path.nil? || gem_path.empty?
|
|
26
|
+
candidates = Dir.glob(File.join(root, 'pkg', 'crudable-rails-*.gem'))
|
|
27
|
+
abort 'No gem found under pkg/. Run gem build first or pass gem_path.' if candidates.empty?
|
|
28
|
+
|
|
29
|
+
gem_path = candidates.max_by { |path| File.mtime(path) }
|
|
30
|
+
else
|
|
31
|
+
gem_path = File.expand_path(gem_path, root)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
abort "Gem not found: #{gem_path}" unless File.file?(gem_path)
|
|
35
|
+
|
|
36
|
+
listing = `tar -xOf "#{gem_path}" data.tar.gz | tar -tvzf -`
|
|
37
|
+
abort 'Could not read gem contents' if listing.empty?
|
|
38
|
+
|
|
39
|
+
bad_entries = listing.lines.map(&:chomp).select do |line|
|
|
40
|
+
path = line.split.last
|
|
41
|
+
next false unless path.start_with?('lib/')
|
|
42
|
+
|
|
43
|
+
mode = line.split.first
|
|
44
|
+
next true unless mode&.start_with?('-')
|
|
45
|
+
|
|
46
|
+
mode[7] != 'r' # other-read in ls -l style (-rwxrwxrwx)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
if bad_entries.any?
|
|
50
|
+
warn 'The following paths in the gem are not world-readable:'
|
|
51
|
+
bad_entries.each { |entry| warn " #{entry}" }
|
|
52
|
+
abort 'release:verify_gem failed'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
controller_line = `tar -xOf "#{gem_path}" data.tar.gz | tar -tvzf - | grep 'lib/crudable/rails/controller.rb'`.strip
|
|
56
|
+
puts 'release:verify_gem passed'
|
|
57
|
+
puts controller_line if controller_line && !controller_line.empty?
|
|
58
|
+
end
|
|
59
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: crudable-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.5.
|
|
4
|
+
version: 1.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tomislav Simnett
|
|
@@ -121,6 +121,7 @@ files:
|
|
|
121
121
|
- lib/generators/crudable/templates/turbo_forms/edit.turbo_stream.erb.tt
|
|
122
122
|
- lib/generators/crudable/templates/turbo_forms/new.turbo_stream.erb.tt
|
|
123
123
|
- lib/tasks/crudable_tasks.rake
|
|
124
|
+
- lib/tasks/release.rake
|
|
124
125
|
homepage: https://gitlab.com/initforthe/crudable-rails
|
|
125
126
|
licenses:
|
|
126
127
|
- MIT
|