plutonium 0.18.5 → 0.18.6
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/app/assets/plutonium.js +1 -1
- data/app/assets/plutonium.js.map +2 -2
- data/app/assets/plutonium.min.js +1 -1
- data/app/assets/plutonium.min.js.map +2 -2
- data/app/views/resource/interactive_bulk_action.html.erb +1 -1
- data/app/views/resource/interactive_resource_action.html.erb +1 -1
- data/lib/generators/pu/eject/layout/layout_generator.rb +1 -2
- data/lib/generators/pu/eject/shell/shell_generator.rb +1 -3
- data/lib/generators/pu/lib/plutonium_generators/concerns/logger.rb +4 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/package_selector.rb +80 -0
- data/lib/generators/pu/lib/plutonium_generators/concerns/resource_selector.rb +48 -0
- data/lib/generators/pu/lib/plutonium_generators/generator.rb +2 -42
- data/lib/generators/pu/lib/plutonium_generators/model_generator_base.rb +1 -4
- data/lib/generators/pu/res/conn/conn_generator.rb +9 -21
- data/lib/generators/pu/res/scaffold/scaffold_generator.rb +10 -5
- data/lib/plutonium/resource/controller.rb +3 -3
- data/lib/plutonium/resource/controllers/authorizable.rb +1 -1
- data/lib/plutonium/resource/controllers/crud_actions.rb +17 -17
- data/lib/plutonium/resource/controllers/interactive_actions.rb +3 -3
- data/lib/plutonium/resource/controllers/presentable.rb +2 -2
- data/lib/plutonium/resource/record/associated_with.rb +83 -0
- data/lib/plutonium/resource/record/associations.rb +92 -0
- data/lib/plutonium/resource/record/field_names.rb +83 -0
- data/lib/plutonium/resource/record/labeling.rb +19 -0
- data/lib/plutonium/resource/record/routes.rb +66 -0
- data/lib/plutonium/resource/record.rb +6 -258
- data/lib/plutonium/ui/breadcrumbs.rb +4 -4
- data/lib/plutonium/ui/component/methods.rb +4 -12
- data/lib/plutonium/ui/form/base.rb +22 -10
- data/lib/plutonium/ui/form/components/secure_association.rb +112 -0
- data/lib/plutonium/ui/form/components/secure_polymorphic_association.rb +54 -0
- data/lib/plutonium/ui/form/concerns/renders_nested_resource_fields.rb +0 -1
- data/lib/plutonium/ui/form/theme.rb +12 -1
- data/lib/plutonium/ui/page/show.rb +1 -1
- data/lib/plutonium/ui/page_header.rb +1 -1
- data/lib/plutonium/version.rb +1 -1
- data/package-lock.json +2 -2
- data/package.json +1 -1
- data/src/js/controllers/slim_select_controller.js +3 -1
- metadata +11 -4
- data/lib/plutonium/ui/form/components/belongs_to.rb +0 -66
- data/lib/plutonium/ui/form/components/has_many.rb +0 -66
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/plutonium/resource/associations.rb
|
4
|
+
module Plutonium
|
5
|
+
module Resource
|
6
|
+
module Record
|
7
|
+
module Associations
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def belongs_to(name, scope = nil, **options)
|
12
|
+
super
|
13
|
+
include_secure_association_methods(:belongs_to, name)
|
14
|
+
end
|
15
|
+
|
16
|
+
def has_one(name, scope = nil, **options)
|
17
|
+
super
|
18
|
+
include_secure_association_methods(:has_one, name)
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_many(name, scope = nil, **options)
|
22
|
+
super
|
23
|
+
include_secure_association_methods(:has_many, name)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_and_belongs_to_many(name, scope = nil, **options)
|
27
|
+
super
|
28
|
+
include_secure_association_methods(:has_and_belongs_to_many, name)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def include_secure_association_methods(association_type, name)
|
34
|
+
mod = Module.new
|
35
|
+
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
36
|
+
extend ActiveSupport::Concern
|
37
|
+
|
38
|
+
#{generate_sgid_methods(association_type, name)}
|
39
|
+
|
40
|
+
define_singleton_method(:to_s) { "Plutonium::Resource::Record::Associations::#{association_type.to_s.camelize}(:#{name})" }
|
41
|
+
define_singleton_method(:inspect) { "Plutonium::Resource::Record::Associations::#{association_type.to_s.camelize}(:#{name})" }
|
42
|
+
RUBY
|
43
|
+
include mod
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_sgid_methods(association_type, name)
|
47
|
+
case association_type
|
48
|
+
when :belongs_to, :has_one
|
49
|
+
generate_singular_sgid_methods(name)
|
50
|
+
when :has_many, :has_and_belongs_to_many
|
51
|
+
generate_collection_sgid_methods(name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def generate_singular_sgid_methods(name)
|
56
|
+
<<-RUBY
|
57
|
+
def #{name}_sgid
|
58
|
+
#{name}&.to_signed_global_id
|
59
|
+
end
|
60
|
+
|
61
|
+
def #{name}_sgid=(sgid)
|
62
|
+
self.#{name} = GlobalID::Locator.locate_signed(sgid)
|
63
|
+
end
|
64
|
+
RUBY
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_collection_sgid_methods(name)
|
68
|
+
<<-RUBY
|
69
|
+
def #{name.to_s.singularize}_sgids
|
70
|
+
#{name}.map(&:to_signed_global_id)
|
71
|
+
end
|
72
|
+
|
73
|
+
def #{name.to_s.singularize}_sgids=(sgids)
|
74
|
+
self.#{name} = GlobalID::Locator.locate_many_signed(sgids)
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_#{name.to_s.singularize}_sgid(sgid)
|
78
|
+
record = GlobalID::Locator.locate_signed(sgid)
|
79
|
+
#{name} << record if record
|
80
|
+
end
|
81
|
+
|
82
|
+
def remove_#{name.to_s.singularize}_sgid(sgid)
|
83
|
+
record = GlobalID::Locator.locate_signed(sgid)
|
84
|
+
#{name}.delete(record) if record
|
85
|
+
end
|
86
|
+
RUBY
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/plutonium/resource/associations.rb
|
4
|
+
module Plutonium
|
5
|
+
module Resource
|
6
|
+
module Record
|
7
|
+
module FieldNames
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def resource_field_names
|
12
|
+
return @resource_field_names if defined?(@resource_field_names) && !Rails.env.local?
|
13
|
+
|
14
|
+
@resource_field_names = gather_resource_field_names
|
15
|
+
end
|
16
|
+
|
17
|
+
def belongs_to_association_field_names
|
18
|
+
return @belongs_to_association_field_names if defined?(@belongs_to_association_field_names) && !Rails.env.local?
|
19
|
+
|
20
|
+
@belongs_to_association_field_names = reflect_on_all_associations(:belongs_to).map(&:name)
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_one_association_field_names
|
24
|
+
return @has_one_association_field_names if defined?(@has_one_association_field_names) && !Rails.env.local?
|
25
|
+
|
26
|
+
@has_one_association_field_names = reflect_on_all_associations(:has_one)
|
27
|
+
.map { |assoc| (!/_attachment$|_blob$/.match?(assoc.name)) ? assoc.name : nil }
|
28
|
+
.compact
|
29
|
+
end
|
30
|
+
|
31
|
+
def has_many_association_field_names
|
32
|
+
return @has_many_association_field_names if defined?(@has_many_association_field_names) && !Rails.env.local?
|
33
|
+
|
34
|
+
@has_many_association_field_names = reflect_on_all_associations(:has_many)
|
35
|
+
.map { |assoc| (!/_attachments$|_blobs$/.match?(assoc.name)) ? assoc.name : nil }
|
36
|
+
.compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_one_attached_field_names
|
40
|
+
return @has_one_attached_field_names if defined?(@has_one_attached_field_names) && !Rails.env.local?
|
41
|
+
|
42
|
+
@has_one_attached_field_names = if respond_to?(:reflect_on_all_attachments)
|
43
|
+
reflect_on_all_attachments
|
44
|
+
.select { |a| a.macro == :has_one_attached }
|
45
|
+
.map(&:name)
|
46
|
+
else
|
47
|
+
[]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def has_many_attached_field_names
|
52
|
+
return @has_many_attached_field_names if defined?(@has_many_attached_field_names) && !Rails.env.local?
|
53
|
+
|
54
|
+
@has_many_attached_field_names = if respond_to?(:reflect_on_all_attachments)
|
55
|
+
reflect_on_all_attachments
|
56
|
+
.select { |a| a.macro == :has_many_attached }
|
57
|
+
.map(&:name)
|
58
|
+
else
|
59
|
+
[]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def content_column_field_names
|
64
|
+
return @content_column_field_names if defined?(@content_column_field_names) && !Rails.env.local?
|
65
|
+
|
66
|
+
@content_column_field_names = content_columns.map { |col| col.name.to_sym }
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def gather_resource_field_names
|
72
|
+
belongs_to_association_field_names +
|
73
|
+
has_one_attached_field_names +
|
74
|
+
has_one_association_field_names +
|
75
|
+
has_many_attached_field_names +
|
76
|
+
has_many_association_field_names +
|
77
|
+
content_column_field_names
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/plutonium/resource/associations.rb
|
4
|
+
module Plutonium
|
5
|
+
module Resource
|
6
|
+
module Record
|
7
|
+
module Labeling
|
8
|
+
def to_label
|
9
|
+
%i[name title].each do |method|
|
10
|
+
name = send(method) if respond_to?(method)
|
11
|
+
return name if name.present?
|
12
|
+
end
|
13
|
+
|
14
|
+
"#{model_name.human} ##{to_param}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/plutonium/resource/associations.rb
|
4
|
+
module Plutonium
|
5
|
+
module Resource
|
6
|
+
module Record
|
7
|
+
module Routes
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
scope :from_path_param, ->(param) { where(id: param) }
|
12
|
+
end
|
13
|
+
|
14
|
+
class_methods do
|
15
|
+
def has_many_association_routes
|
16
|
+
return @has_many_association_routes if defined?(@has_many_association_routes) && !Rails.env.local?
|
17
|
+
|
18
|
+
@has_many_association_routes = reflect_on_all_associations(:has_many).map { |assoc| assoc.klass.model_name.plural }
|
19
|
+
end
|
20
|
+
|
21
|
+
def all_nested_attributes_options
|
22
|
+
unless Rails.env.local?
|
23
|
+
return @all_nested_attributes_options if defined?(@all_nested_attributes_options)
|
24
|
+
end
|
25
|
+
|
26
|
+
@all_nested_attributes_options = reflect_on_all_associations.map do |association|
|
27
|
+
setter_method = "#{association.name}_attributes="
|
28
|
+
if method_defined?(setter_method)
|
29
|
+
[association.name, nested_attributes_options[association.name].merge(
|
30
|
+
macro: association.macro,
|
31
|
+
class: association.polymorphic? ? nil : association.klass
|
32
|
+
)]
|
33
|
+
end
|
34
|
+
end.compact.to_h
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def path_parameter(param_name)
|
40
|
+
param_name = param_name.to_sym
|
41
|
+
|
42
|
+
scope :from_path_param, ->(param) { where(param_name => param) }
|
43
|
+
|
44
|
+
define_method :to_param do
|
45
|
+
return nil unless persisted?
|
46
|
+
|
47
|
+
send(param_name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def dynamic_path_parameter(param_name)
|
52
|
+
param_name = param_name.to_sym
|
53
|
+
|
54
|
+
scope :from_path_param, ->(param) { where(id: param.split("-").first) }
|
55
|
+
|
56
|
+
define_method :to_param do
|
57
|
+
return nil unless persisted?
|
58
|
+
|
59
|
+
"#{id}-#{send(param_name)}".parameterize
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -2,265 +2,13 @@ module Plutonium
|
|
2
2
|
module Resource
|
3
3
|
module Record
|
4
4
|
extend ActiveSupport::Concern
|
5
|
-
include Plutonium::Models::HasCents
|
6
|
-
|
7
|
-
included do
|
8
|
-
scope :from_path_param, ->(param) { where(id: param) }
|
9
|
-
|
10
|
-
scope :associated_with, ->(record) do
|
11
|
-
named_scope = :"associated_with_#{record.model_name.singular}"
|
12
|
-
return send(named_scope, record) if respond_to?(named_scope)
|
13
|
-
|
14
|
-
# TODO: add support for polymorphic associations
|
15
|
-
# TODO: add logging
|
16
|
-
# TODO: memoize this
|
17
|
-
|
18
|
-
own_association = klass.find_association_from_self_to_record(record)
|
19
|
-
if own_association
|
20
|
-
return klass.query_based_on_association(own_association, record)
|
21
|
-
end
|
22
|
-
|
23
|
-
record_association = klass.find_association_to_self_from_record(record)
|
24
|
-
if record_association
|
25
|
-
# TODO: add a warning here about a potentially poor performing query
|
26
|
-
return where(id: record.public_send(record_association.name))
|
27
|
-
end
|
28
|
-
|
29
|
-
klass.raise_association_error(record, named_scope)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
class_methods do
|
34
|
-
# Returns the resource field names
|
35
|
-
# @return [Array<Symbol>]
|
36
|
-
def resource_field_names
|
37
|
-
return @resource_field_names if defined?(@resource_field_names) && !Rails.env.local?
|
38
|
-
|
39
|
-
@resource_field_names = gather_resource_field_names
|
40
|
-
end
|
41
|
-
|
42
|
-
# Overrides belongs_to to add support for polymorphic associations
|
43
|
-
# @param [Symbol] name The name of the association
|
44
|
-
# @param [Proc] scope The scope for the association
|
45
|
-
# @param [Hash] options The options for the association
|
46
|
-
def belongs_to(name, scope = nil, **options)
|
47
|
-
super
|
48
|
-
|
49
|
-
return unless options[:polymorphic]
|
50
|
-
|
51
|
-
mod = Module.new
|
52
|
-
mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
53
|
-
extend ActiveSupport::Concern
|
54
|
-
|
55
|
-
def #{name}_sgid
|
56
|
-
#{name}&.to_signed_global_id
|
57
|
-
end
|
58
|
-
|
59
|
-
def #{name}_sgid=(sgid)
|
60
|
-
self.#{name} = GlobalID::Locator.locate_signed(sgid)
|
61
|
-
end
|
62
|
-
|
63
|
-
define_singleton_method(:to_s) { "Plutonium::Polymorphic::BelongsTo(:#{name})" }
|
64
|
-
define_singleton_method(:inspect) { "Plutonium::Polymorphic::BelongsTo(:#{name})" }
|
65
|
-
RUBY
|
66
|
-
include mod
|
67
|
-
end
|
68
|
-
|
69
|
-
# Returns the names of belongs_to associations
|
70
|
-
# @return [Array<Symbol>]
|
71
|
-
def belongs_to_association_field_names
|
72
|
-
return @belongs_to_association_field_names if defined?(@belongs_to_association_field_names) && !Rails.env.local?
|
73
|
-
|
74
|
-
@belongs_to_association_field_names = reflect_on_all_associations(:belongs_to).map(&:name)
|
75
|
-
end
|
76
|
-
|
77
|
-
# Returns the names of has_one associations
|
78
|
-
# @return [Array<Symbol>]
|
79
|
-
def has_one_association_field_names
|
80
|
-
return @has_one_association_field_names if defined?(@has_one_association_field_names) && !Rails.env.local?
|
81
|
-
|
82
|
-
@has_one_association_field_names = reflect_on_all_associations(:has_one)
|
83
|
-
.map { |assoc| (!/_attachment$|_blob$/.match?(assoc.name)) ? assoc.name : nil }
|
84
|
-
.compact
|
85
|
-
end
|
86
|
-
|
87
|
-
# Returns the names of has_many associations
|
88
|
-
# @return [Array<Symbol>]
|
89
|
-
def has_many_association_field_names
|
90
|
-
return @has_many_association_field_names if defined?(@has_many_association_field_names) && !Rails.env.local?
|
91
|
-
|
92
|
-
@has_many_association_field_names = reflect_on_all_associations(:has_many)
|
93
|
-
.map { |assoc| (!/_attachments$|_blobs$/.match?(assoc.name)) ? assoc.name : nil }
|
94
|
-
.compact
|
95
|
-
end
|
96
|
-
|
97
|
-
# Returns the names of has_one attached associations
|
98
|
-
# @return [Array<Symbol>]
|
99
|
-
def has_one_attached_field_names
|
100
|
-
return @has_one_attached_field_names if defined?(@has_one_attached_field_names) && !Rails.env.local?
|
101
|
-
|
102
|
-
@has_one_attached_field_names = if respond_to?(:reflect_on_all_attachments)
|
103
|
-
reflect_on_all_attachments
|
104
|
-
.select { |a| a.macro == :has_one_attached }
|
105
|
-
.map(&:name)
|
106
|
-
else
|
107
|
-
[]
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# Returns the names of has_many attached associations
|
112
|
-
# @return [Array<Symbol>]
|
113
|
-
def has_many_attached_field_names
|
114
|
-
return @has_many_attached_field_names if defined?(@has_many_attached_field_names) && !Rails.env.local?
|
115
5
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
# Returns the names of content columns
|
126
|
-
# @return [Array<Symbol>]
|
127
|
-
def content_column_field_names
|
128
|
-
return @content_column_field_names if defined?(@content_column_field_names) && !Rails.env.local?
|
129
|
-
|
130
|
-
@content_column_field_names = content_columns.map { |col| col.name.to_sym }
|
131
|
-
end
|
132
|
-
|
133
|
-
# Returns the routes for has_many associations
|
134
|
-
# @return [Array<Symbol>]
|
135
|
-
def has_many_association_routes
|
136
|
-
return @has_many_association_routes if defined?(@has_many_association_routes) && !Rails.env.local?
|
137
|
-
|
138
|
-
@has_many_association_routes = reflect_on_all_associations(:has_many).map { |assoc| assoc.klass.model_name.plural }
|
139
|
-
end
|
140
|
-
|
141
|
-
# Returns all nested attributes options
|
142
|
-
# @return [Hash]
|
143
|
-
def all_nested_attributes_options
|
144
|
-
unless Rails.env.local?
|
145
|
-
return @all_nested_attributes_options if defined?(@all_nested_attributes_options)
|
146
|
-
end
|
147
|
-
|
148
|
-
@all_nested_attributes_options = reflect_on_all_associations.map do |association|
|
149
|
-
setter_method = "#{association.name}_attributes="
|
150
|
-
if method_defined?(setter_method)
|
151
|
-
[association.name, nested_attributes_options[association.name].merge(
|
152
|
-
macro: association.macro,
|
153
|
-
class: association.polymorphic? ? nil : association.klass
|
154
|
-
)]
|
155
|
-
end
|
156
|
-
end.compact.to_h
|
157
|
-
end
|
158
|
-
|
159
|
-
# Finds the association to the given record
|
160
|
-
# @param [ActiveRecord::Base] record The record to find the association with
|
161
|
-
# @return [ActiveRecord::Reflection::AssociationReflection, nil]
|
162
|
-
def find_association_from_self_to_record(record)
|
163
|
-
reflect_on_all_associations.find do |assoc|
|
164
|
-
assoc.klass.name == record.class.name unless assoc.polymorphic?
|
165
|
-
rescue
|
166
|
-
assoc.check_validity!
|
167
|
-
raise
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Finds the association to self in the given record
|
172
|
-
# @param [ActiveRecord::Base] record The record to find the association with
|
173
|
-
# @return [ActiveRecord::Reflection::AssociationReflection, nil]
|
174
|
-
def find_association_to_self_from_record(record)
|
175
|
-
record.class.reflect_on_all_associations.find do |assoc|
|
176
|
-
assoc.klass.name == name
|
177
|
-
rescue
|
178
|
-
assoc.check_validity!
|
179
|
-
raise
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# Queries based on the association type
|
184
|
-
# @param [ActiveRecord::Reflection::AssociationReflection] assoc The association
|
185
|
-
# @param [ActiveRecord::Base] record The record to query with
|
186
|
-
# @return [ActiveRecord::Relation]
|
187
|
-
def query_based_on_association(assoc, record)
|
188
|
-
case assoc.macro
|
189
|
-
when :has_one
|
190
|
-
joins(assoc.name).where(assoc.name => {record.class.primary_key => record.id})
|
191
|
-
when :belongs_to
|
192
|
-
where(assoc.name => record)
|
193
|
-
when :has_many
|
194
|
-
joins(assoc.name).where(assoc.klass.table_name => record)
|
195
|
-
else
|
196
|
-
raise NotImplementedError, "associated_with->##{assoc.macro}"
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
# Raises an error for unresolved associations
|
201
|
-
# @param [ActiveRecord::Base] record The record with unresolved association
|
202
|
-
# @param [Symbol] named_scope The named scope
|
203
|
-
# @raise [RuntimeError]
|
204
|
-
def raise_association_error(record, named_scope)
|
205
|
-
raise "Could not resolve the association between '#{name}' and '#{record.class.name}'\n\n" \
|
206
|
-
"Define\n" \
|
207
|
-
" 1. the associations between the models\n" \
|
208
|
-
" 2. a named scope on #{name} e.g.\n\n" \
|
209
|
-
"scope :#{named_scope}, ->(#{record.model_name.singular}) { do_something_here }"
|
210
|
-
end
|
211
|
-
|
212
|
-
private
|
213
|
-
|
214
|
-
# Defines a scope and method for path parameters
|
215
|
-
# @param [Symbol] param_name The name of the parameter
|
216
|
-
def path_parameter(param_name)
|
217
|
-
param_name = param_name.to_sym
|
218
|
-
|
219
|
-
scope :from_path_param, ->(param) { where(param_name => param) }
|
220
|
-
|
221
|
-
define_method :to_param do
|
222
|
-
return nil unless persisted?
|
223
|
-
|
224
|
-
send(param_name)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
# Defines a scope and method for dynamic path parameters
|
229
|
-
# @param [Symbol] param_name The name of the parameter
|
230
|
-
def dynamic_path_parameter(param_name)
|
231
|
-
param_name = param_name.to_sym
|
232
|
-
|
233
|
-
scope :from_path_param, ->(param) { where(id: param.split("-").first) }
|
234
|
-
|
235
|
-
define_method :to_param do
|
236
|
-
return nil unless persisted?
|
237
|
-
|
238
|
-
"#{id}-#{send(param_name)}".parameterize
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
# Gathers all resource field names
|
243
|
-
# @return [Array<Symbol>]
|
244
|
-
def gather_resource_field_names
|
245
|
-
belongs_to_association_field_names +
|
246
|
-
has_one_attached_field_names +
|
247
|
-
has_one_association_field_names +
|
248
|
-
has_many_attached_field_names +
|
249
|
-
has_many_association_field_names +
|
250
|
-
content_column_field_names
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
# Returns a label for the record
|
255
|
-
# @return [String]
|
256
|
-
def to_label
|
257
|
-
%i[name title].each do |method|
|
258
|
-
name = send(method) if respond_to?(method)
|
259
|
-
return name if name.present?
|
260
|
-
end
|
261
|
-
|
262
|
-
"#{model_name.human} ##{to_param}"
|
263
|
-
end
|
6
|
+
include Plutonium::Models::HasCents
|
7
|
+
include Plutonium::Resource::Record::Routes
|
8
|
+
include Plutonium::Resource::Record::Labeling
|
9
|
+
include Plutonium::Resource::Record::FieldNames
|
10
|
+
include Plutonium::Resource::Record::Associations
|
11
|
+
include Plutonium::Resource::Record::AssociatedWith
|
264
12
|
end
|
265
13
|
end
|
266
14
|
end
|
@@ -87,7 +87,7 @@ module Plutonium
|
|
87
87
|
end
|
88
88
|
|
89
89
|
# Record
|
90
|
-
if resource_record
|
90
|
+
if resource_record?
|
91
91
|
# Record Resource
|
92
92
|
li(class: "flex items-center") do
|
93
93
|
svg(
|
@@ -112,7 +112,7 @@ module Plutonium
|
|
112
112
|
end
|
113
113
|
|
114
114
|
# Record Itself
|
115
|
-
if resource_record
|
115
|
+
if resource_record!.persisted? && action_name != "show"
|
116
116
|
li(class: "flex items-center") do
|
117
117
|
svg(
|
118
118
|
class: "rtl:rotate-180 block w-3 h-3 mx-1 text-gray-400",
|
@@ -129,8 +129,8 @@ module Plutonium
|
|
129
129
|
d: "m1 9 4-4-4-4"
|
130
130
|
)
|
131
131
|
end
|
132
|
-
link_to display_name_of(resource_record),
|
133
|
-
resource_url_for(resource_record),
|
132
|
+
link_to display_name_of(resource_record!),
|
133
|
+
resource_url_for(resource_record!),
|
134
134
|
class:
|
135
135
|
"ms-1 text-sm font-medium text-gray-700 hover:text-primary-600 md:ms-2 dark:text-gray-200 dark:hover:text-white"
|
136
136
|
end
|
@@ -10,18 +10,6 @@ module Plutonium
|
|
10
10
|
|
11
11
|
private
|
12
12
|
|
13
|
-
def resource_class
|
14
|
-
helpers.controller.send(:resource_class)
|
15
|
-
end
|
16
|
-
|
17
|
-
def resource_record
|
18
|
-
helpers.controller.send(:resource_record)
|
19
|
-
end
|
20
|
-
|
21
|
-
def current_parent
|
22
|
-
helpers.controller.send(:current_parent)
|
23
|
-
end
|
24
|
-
|
25
13
|
def params
|
26
14
|
helpers.controller.params
|
27
15
|
end
|
@@ -35,11 +23,15 @@ module Plutonium
|
|
35
23
|
end
|
36
24
|
|
37
25
|
delegate \
|
26
|
+
:resource_class,
|
27
|
+
:resource_record!,
|
28
|
+
:resource_record?,
|
38
29
|
:resource_name,
|
39
30
|
:resource_name_plural,
|
40
31
|
:display_name_of,
|
41
32
|
:resource_url_for,
|
42
33
|
:current_user,
|
34
|
+
:current_parent,
|
43
35
|
:current_definition,
|
44
36
|
:current_query_object,
|
45
37
|
:raw_resource_query_params,
|
@@ -19,16 +19,6 @@ module Plutonium
|
|
19
19
|
select_tag(**attributes, class!: "", &)
|
20
20
|
end
|
21
21
|
|
22
|
-
def belongs_to_tag(**attributes, &)
|
23
|
-
attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
|
24
|
-
create_component(Components::BelongsTo, :belongs_to, **attributes, &)
|
25
|
-
end
|
26
|
-
|
27
|
-
def has_many_tag(**attributes, &)
|
28
|
-
attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
|
29
|
-
create_component(Components::HasMany, :has_many, **attributes, &)
|
30
|
-
end
|
31
|
-
|
32
22
|
def flatpickr_tag(**, &)
|
33
23
|
create_component(Components::Flatpickr, :flatpickr, **, &)
|
34
24
|
end
|
@@ -42,6 +32,28 @@ module Plutonium
|
|
42
32
|
create_component(Components::Uppy, :uppy, **, &)
|
43
33
|
end
|
44
34
|
alias_method :file_tag, :uppy_tag
|
35
|
+
|
36
|
+
def secure_association_tag(**attributes, &)
|
37
|
+
attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
|
38
|
+
create_component(Components::SecureAssociation, :association, **attributes, &)
|
39
|
+
end
|
40
|
+
# preserve original methods with prefix
|
41
|
+
alias_method :basic_belongs_to_tag, :belongs_to_tag
|
42
|
+
alias_method :basic_has_many_tag, :has_many_tag
|
43
|
+
alias_method :basic_has_one_tag, :has_one_tag
|
44
|
+
# use new methods as defaults
|
45
|
+
alias_method :belongs_to_tag, :secure_association_tag
|
46
|
+
alias_method :has_many_tag, :secure_association_tag
|
47
|
+
alias_method :has_one_tag, :secure_association_tag
|
48
|
+
|
49
|
+
def secure_polymorphic_association_tag(**attributes, &)
|
50
|
+
attributes[:data_controller] = tokens(attributes[:data_controller], "slim-select") # TODO: put this behind a config
|
51
|
+
create_component(Components::SecurePolymorphicAssociation, :polymorphic_association, **attributes, &)
|
52
|
+
end
|
53
|
+
# preserve original methods with prefix
|
54
|
+
alias_method :basic_polymorphic_belongs_to_tag, :polymorphic_belongs_to_tag
|
55
|
+
# use new methods as defaults
|
56
|
+
alias_method :polymorphic_belongs_to_tag, :secure_polymorphic_association_tag
|
45
57
|
end
|
46
58
|
|
47
59
|
private
|