dry_rails 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/views/_form.haml +32 -0
- data/app/views/_form_errors.haml +5 -0
- data/app/views/edit.haml +15 -0
- data/app/views/index.haml +62 -0
- data/app/views/new.haml +10 -0
- data/lib/dry/controller.rb +134 -0
- data/lib/dry/resource.rb +100 -0
- data/lib/dry/resource_routes.rb +20 -0
- data/lib/dry/routing_helpers.rb +49 -0
- data/lib/dry/template_resolver.rb +11 -0
- data/lib/dry/version.rb +3 -0
- data/lib/dry.rb +13 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 45e9f1560278be794de82bb4b02b2810eaa2cf0754216b90449179fab98da9f1
|
4
|
+
data.tar.gz: 112c9c2b20d87a231e76213e910c3510404466d22fe527a0727ded5c32b77b6f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1d3a39eb7221fd5de5a04fae053a346007d2b0e4024e875ee5eff291587f232bdc43da69abfdc847b3c49fdfecfa32ae8cce359dc7ec78534e29ec5e21600ef8
|
7
|
+
data.tar.gz: 0cc139ffa109deeea728d3fd03b6313eafe6b485690e9a4a5e2132f561ef9f03ccc21a8df9040d67c97782ac4fff56aa76c0026fa8f3a188ddc54b2deedc5816
|
@@ -0,0 +1,32 @@
|
|
1
|
+
= form_for form_arguments(@record), html: { class: 'form' } do |f|
|
2
|
+
%fieldset
|
3
|
+
- if lookup_context.exists?('form_fieldset_before',
|
4
|
+
%W[#{@resource.model_name.route_key}/dry], true)
|
5
|
+
= render "#{@resource.model_name.route_key}/dry/form_fieldset_before"
|
6
|
+
|
7
|
+
- @resource.each_form_fields do |attr, type|
|
8
|
+
%p.field
|
9
|
+
- case type
|
10
|
+
- when Class
|
11
|
+
= f.label attr
|
12
|
+
%br
|
13
|
+
= f.collection_select attr, type.send(:all), :id, :to_s
|
14
|
+
- when Symbol
|
15
|
+
- if type == :check_box
|
16
|
+
= f.send type, attr
|
17
|
+
= f.label attr
|
18
|
+
- else
|
19
|
+
= f.label attr
|
20
|
+
%br
|
21
|
+
- form_control = ['form_field_for',
|
22
|
+
@resource.model_name.singular_route_key,
|
23
|
+
attr].join(?_).to_sym
|
24
|
+
- if respond_to? form_control
|
25
|
+
= send form_control, f
|
26
|
+
- else
|
27
|
+
= f.send type, attr
|
28
|
+
|
29
|
+
- if @record.errors.any?
|
30
|
+
= render "form_errors", record: @record
|
31
|
+
|
32
|
+
%p= f.button
|
data/app/views/edit.haml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
%h1
|
2
|
+
Editing
|
3
|
+
= @resource.singular_name
|
4
|
+
|
5
|
+
|
6
|
+
= render 'form'
|
7
|
+
|
8
|
+
%ul.actions
|
9
|
+
- if @resource.relations?
|
10
|
+
- @resource.relations.each do |relation|
|
11
|
+
- relation = @record.send(relation)
|
12
|
+
%li= link_to relation.model_name.human.pluralize,
|
13
|
+
relation_path(@record, relation)
|
14
|
+
%li
|
15
|
+
= link_to 'Back', collection_path(@resource)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
%h1
|
2
|
+
Listing
|
3
|
+
= @resource.plural_name
|
4
|
+
|
5
|
+
|
6
|
+
- if @collection.empty?
|
7
|
+
%p
|
8
|
+
No
|
9
|
+
= @resource.singular_name
|
10
|
+
found.
|
11
|
+
|
12
|
+
- else
|
13
|
+
%table.list
|
14
|
+
%thead
|
15
|
+
%tr
|
16
|
+
%th
|
17
|
+
= @resource.singular_name.capitalize
|
18
|
+
- @resource.attrs_read.each do |attr|
|
19
|
+
%th= attr.capitalize
|
20
|
+
- if @resource.edit? || @resource.destroy?
|
21
|
+
%th.list-actions
|
22
|
+
Actions
|
23
|
+
|
24
|
+
%tbody
|
25
|
+
- @collection.each do |record|
|
26
|
+
%tr
|
27
|
+
%td
|
28
|
+
- if @resource.show?
|
29
|
+
= link_to record, record_path(record)
|
30
|
+
- else
|
31
|
+
= link_to record, edit_path(record)
|
32
|
+
- @resource.attrs_read.each do |attr|
|
33
|
+
%td
|
34
|
+
- attr_content = ['read_attr_content',
|
35
|
+
@resource.model_name.singular_route_key,
|
36
|
+
attr].join(?_).to_sym
|
37
|
+
- if respond_to? attr_content
|
38
|
+
= send attr_content, record
|
39
|
+
- else
|
40
|
+
= record.send attr
|
41
|
+
- if @resource.edit? || @resource.destroy?
|
42
|
+
%td.list-actions
|
43
|
+
%ul.actions
|
44
|
+
- if @resource.edit?
|
45
|
+
%li= link_to 'Edit', edit_path(record)
|
46
|
+
- if @resource.destroy?
|
47
|
+
%li= link_to 'Destroy', record_path(record), method: :delete,
|
48
|
+
data: { confirm: t('confirmation',
|
49
|
+
default: 'Are you sure?') }
|
50
|
+
- if @resource.relations?
|
51
|
+
- @resource.relations.each do |relation|
|
52
|
+
- relation = record.send(relation)
|
53
|
+
%li= link_to relation.model_name.human.pluralize,
|
54
|
+
relation_path(record, relation)
|
55
|
+
|
56
|
+
|
57
|
+
%ul.actions
|
58
|
+
- if @resource.new?
|
59
|
+
%li
|
60
|
+
= link_to "New #{@resource.singular_name}", new_path(@resource)
|
61
|
+
- if lookup_context.exists?('index_actions_extra', %w[dry], true)
|
62
|
+
= render 'dry/index_actions_extra'
|
data/app/views/new.haml
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
module Dry
|
2
|
+
module Controller
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
include RoutingHelpers
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_attribute :_dry_scope, instance_accessor: false
|
8
|
+
|
9
|
+
class_attribute :_dry_attrs, instance_accessor: false
|
10
|
+
self._dry_attrs = { read: [], write: [], options: {} }
|
11
|
+
|
12
|
+
class_attribute :_dry_nested_relations, instance_accessor: false
|
13
|
+
self._dry_nested_relations = []
|
14
|
+
|
15
|
+
append_view_path TemplateResolver.new
|
16
|
+
|
17
|
+
helper RoutingHelpers
|
18
|
+
|
19
|
+
before_filter :set_resource
|
20
|
+
before_filter :set_collection, only: :index
|
21
|
+
before_filter :set_record, only: %i[show edit update destroy]
|
22
|
+
end
|
23
|
+
|
24
|
+
module ClassMethods
|
25
|
+
def dry_scope &block
|
26
|
+
self._dry_scope = block
|
27
|
+
end
|
28
|
+
|
29
|
+
def dry_attrs_read *attrs
|
30
|
+
self._dry_attrs[:read] = attrs
|
31
|
+
end
|
32
|
+
|
33
|
+
def dry_attrs_write *attrs
|
34
|
+
self._dry_attrs[:write] = attrs
|
35
|
+
end
|
36
|
+
|
37
|
+
def dry_attrs_options **options
|
38
|
+
self._dry_attrs[:options] = options
|
39
|
+
end
|
40
|
+
|
41
|
+
def dry_nest *relations
|
42
|
+
self._dry_nested_relations.push *relations
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def index
|
47
|
+
end
|
48
|
+
|
49
|
+
def show
|
50
|
+
end
|
51
|
+
|
52
|
+
def new
|
53
|
+
@record = resource_scope.new
|
54
|
+
end
|
55
|
+
|
56
|
+
def edit
|
57
|
+
end
|
58
|
+
|
59
|
+
def create
|
60
|
+
@record = resource_scope.new record_params
|
61
|
+
if @record.save
|
62
|
+
redirect_to collection_path(@resource),
|
63
|
+
notice: "#{model_name.singular.capitalize} was successfully created."
|
64
|
+
else
|
65
|
+
render :new
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def update
|
70
|
+
if @record.update record_params
|
71
|
+
redirect_to collection_path(@resource),
|
72
|
+
notice: "#{model_name.singular.capitalize} was successfully updated."
|
73
|
+
else
|
74
|
+
render :edit
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def destroy
|
79
|
+
@record.destroy
|
80
|
+
redirect_to collection_path(@resource),
|
81
|
+
notice: "#{model_name.singular.capitalize} was successfully destroyed."
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def resource
|
87
|
+
@resource ||= Resource.new(controller_name.classify.constantize,
|
88
|
+
attrs_read: self.class._dry_attrs[:read],
|
89
|
+
attrs_write: self.class._dry_attrs[:write],
|
90
|
+
attrs_options: self.class._dry_attrs[:options],
|
91
|
+
relations: self.class._dry_nested_relations,
|
92
|
+
routes: resource_routes
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def resource_routes
|
97
|
+
ResourceRoutes.new(Rails.application.routes.routes, controller_path)
|
98
|
+
.routes
|
99
|
+
end
|
100
|
+
|
101
|
+
def resource_scope
|
102
|
+
if b = self.class._dry_scope
|
103
|
+
instance_exec &b
|
104
|
+
else
|
105
|
+
resource.model
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def model_name
|
110
|
+
resource.model_name
|
111
|
+
end
|
112
|
+
|
113
|
+
def collection
|
114
|
+
resource_scope.order 'created_at ASC'
|
115
|
+
end
|
116
|
+
|
117
|
+
def set_resource
|
118
|
+
resource
|
119
|
+
end
|
120
|
+
|
121
|
+
def set_collection
|
122
|
+
@collection = collection
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_record
|
126
|
+
@record = resource_scope.find params[:id]
|
127
|
+
end
|
128
|
+
|
129
|
+
def record_params
|
130
|
+
params.require(model_name.param_key.to_sym)
|
131
|
+
.permit *self.class._dry_attrs[:write]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/dry/resource.rb
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
module Dry
|
2
|
+
class Resource
|
3
|
+
DEFAULT_OPTIONS = {
|
4
|
+
attrs_read: [],
|
5
|
+
attrs_write: [],
|
6
|
+
attrs_options: {},
|
7
|
+
relations: [],
|
8
|
+
routes: []
|
9
|
+
}
|
10
|
+
|
11
|
+
ATTR_TYPE_TO_FORM_FIELD = {
|
12
|
+
boolean: :check_box,
|
13
|
+
decimal: :number_field,
|
14
|
+
integer: :number_field,
|
15
|
+
string: :text_field,
|
16
|
+
text: :text_area
|
17
|
+
}
|
18
|
+
|
19
|
+
ATTR_RELATION_PATTERN = /_id\z/.freeze
|
20
|
+
|
21
|
+
extend Forwardable
|
22
|
+
def_delegators :@model, :model_name
|
23
|
+
|
24
|
+
attr_reader :model
|
25
|
+
|
26
|
+
def initialize model, options = {}
|
27
|
+
@model = model
|
28
|
+
@options = DEFAULT_OPTIONS.merge options
|
29
|
+
end
|
30
|
+
|
31
|
+
def singular_name
|
32
|
+
model_name.singular
|
33
|
+
end
|
34
|
+
|
35
|
+
def plural_name
|
36
|
+
model_name.plural
|
37
|
+
end
|
38
|
+
|
39
|
+
def relations?
|
40
|
+
@options[:relations].any?
|
41
|
+
end
|
42
|
+
|
43
|
+
def relations
|
44
|
+
@options[:relations]
|
45
|
+
end
|
46
|
+
|
47
|
+
def show?
|
48
|
+
has_route_for? :show
|
49
|
+
end
|
50
|
+
|
51
|
+
def new?
|
52
|
+
has_route_for? :new
|
53
|
+
end
|
54
|
+
|
55
|
+
def edit?
|
56
|
+
has_route_for? :edit
|
57
|
+
end
|
58
|
+
|
59
|
+
def destroy?
|
60
|
+
has_route_for? :destroy
|
61
|
+
end
|
62
|
+
|
63
|
+
def attrs_read
|
64
|
+
@options[:attrs_read]
|
65
|
+
end
|
66
|
+
|
67
|
+
def attrs_write
|
68
|
+
@options[:attrs_write]
|
69
|
+
end
|
70
|
+
|
71
|
+
def attrs_options
|
72
|
+
@options[:attrs_options]
|
73
|
+
end
|
74
|
+
|
75
|
+
def each_form_fields
|
76
|
+
attrs_write.each do |e|
|
77
|
+
if e =~ ATTR_RELATION_PATTERN
|
78
|
+
yield e,
|
79
|
+
@model.reflections[e.to_s.sub ATTR_RELATION_PATTERN, ''].klass
|
80
|
+
else
|
81
|
+
yield e, form_field_for(e)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def has_route_for? action
|
89
|
+
@options[:routes].include? action
|
90
|
+
end
|
91
|
+
|
92
|
+
def form_field_for attr
|
93
|
+
if type = attrs_options[attr]
|
94
|
+
type
|
95
|
+
else
|
96
|
+
ATTR_TYPE_TO_FORM_FIELD[@model.column_types[attr.to_s].type]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Dry
|
2
|
+
class ResourceRoutes
|
3
|
+
def initialize routes, path
|
4
|
+
@routes = routes
|
5
|
+
@path = path
|
6
|
+
end
|
7
|
+
|
8
|
+
def routes
|
9
|
+
routes_for_path(@path).each_with_object([]) do |e, m|
|
10
|
+
m << e.defaults[:action].to_sym
|
11
|
+
end.uniq
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def routes_for_path path
|
17
|
+
@routes.select { |e| e.defaults[:controller] == @path }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Dry
|
2
|
+
module RoutingHelpers
|
3
|
+
def collection_path resource
|
4
|
+
send "#{base_path resource, plural: true}_path"
|
5
|
+
end
|
6
|
+
|
7
|
+
def record_path record
|
8
|
+
send "#{base_path record.class}_path", *([@parent, record].compact)
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_path resource
|
12
|
+
send "new_#{base_path resource}_path"
|
13
|
+
end
|
14
|
+
|
15
|
+
def edit_path record
|
16
|
+
send "edit_#{base_path record.class}_path", *([@parent, record].compact)
|
17
|
+
end
|
18
|
+
|
19
|
+
def relation_path record, relation
|
20
|
+
send "#{base_path record.class}_#{relation.model_name.route_key}_path",
|
21
|
+
record
|
22
|
+
end
|
23
|
+
|
24
|
+
def form_arguments record
|
25
|
+
[*current_namespace, @parent, record].compact
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def current_namespace
|
31
|
+
(controller_path.split('/') - [controller_name]).map &:to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def base_path klass, plural: false
|
35
|
+
path = [*current_namespace].flatten
|
36
|
+
path << parent_class.model_name.singular_route_key if parent?
|
37
|
+
path << klass.model_name.send(plural ? :route_key : :singular_route_key)
|
38
|
+
path * '_'
|
39
|
+
end
|
40
|
+
|
41
|
+
def parent?
|
42
|
+
!!@parent
|
43
|
+
end
|
44
|
+
|
45
|
+
def parent_class
|
46
|
+
@parent ? @parent.class : nil
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/dry/version.rb
ADDED
data/lib/dry.rb
ADDED
metadata
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dry_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Thibault Jouan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: railties
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: haml
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activerecord
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '4.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: capybara
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.4'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.4'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-rails
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.3'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sqlite3
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.3'
|
104
|
+
- - "<"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '1.4'
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '1.3'
|
114
|
+
- - "<"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '1.4'
|
117
|
+
description:
|
118
|
+
email: tj@a13.fr
|
119
|
+
executables: []
|
120
|
+
extensions: []
|
121
|
+
extra_rdoc_files: []
|
122
|
+
files:
|
123
|
+
- app/views/_form.haml
|
124
|
+
- app/views/_form_errors.haml
|
125
|
+
- app/views/edit.haml
|
126
|
+
- app/views/index.haml
|
127
|
+
- app/views/new.haml
|
128
|
+
- lib/dry.rb
|
129
|
+
- lib/dry/controller.rb
|
130
|
+
- lib/dry/resource.rb
|
131
|
+
- lib/dry/resource_routes.rb
|
132
|
+
- lib/dry/routing_helpers.rb
|
133
|
+
- lib/dry/template_resolver.rb
|
134
|
+
- lib/dry/version.rb
|
135
|
+
homepage:
|
136
|
+
licenses:
|
137
|
+
- BSD-3-Clause
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubygems_version: 3.0.3
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: Dry
|
158
|
+
test_files: []
|