@@ -2,60 +2,49 @@ module Jsonapi
2
2
class ResourceGenerator < ::Rails ::Generators ::NamedBase
3
3
source_root File . expand_path ( '../templates' , __FILE__ )
4
4
5
+ argument :attributes , type : :array , default : [ ] , banner : "field[:type][:index] field[:type][:index]"
6
+
5
7
class_option :'omit-comments' ,
6
8
type : :boolean ,
7
9
default : false ,
8
10
aliases : [ '--omit-comments' , '-c' ] ,
9
11
desc : 'Generate without documentation comments'
10
- class_option :'omit-controller' ,
11
- type : :boolean ,
12
- default : false ,
13
- aliases : [ '--omit-controller' ] ,
14
- desc : 'Generate without controller'
15
- class_option :'omit-serializer' ,
16
- type : :boolean ,
17
- default : false ,
18
- aliases : [ '--omit-serializer' , '-s' ] ,
19
- desc : 'Generate without serializer'
20
- class_option :'omit-payload' ,
21
- type : :boolean ,
22
- default : false ,
23
- aliases : [ '--omit-payload' , '-p' ] ,
24
- desc : 'Generate without spec payload'
25
- class_option :'omit-strong-resource' ,
26
- type : :boolean ,
27
- default : false ,
28
- aliases : [ '--omit-strong-resource' , '-r' ] ,
29
- desc : 'Generate without strong resource'
30
- class_option :'omit-route' ,
31
- type : :boolean ,
32
- default : false ,
33
- aliases : [ '--omit-route' ] ,
34
- desc : 'Generate without specs'
35
- class_option :'omit-tests' ,
36
- type : :boolean ,
37
- default : false ,
38
- aliases : [ '--omit-tests' , '-t' ] ,
39
- desc : 'Generate without specs'
12
+ class_option :'actions' ,
13
+ type : :array ,
14
+ default : nil ,
15
+ aliases : [ '--actions' , '-a' ] ,
16
+ desc : 'Array of controller actions to support, e.g. "index show destroy"'
40
17
41
18
desc "This generator creates a resource file at app/resources, as well as corresponding controller/specs/route/etc"
42
19
def copy_resource_file
43
20
unless model_klass
44
21
raise "You must define a #{ class_name } model before generating the corresponding resource."
45
22
end
46
23
47
- generate_controller unless omit_controller?
48
- generate_serializer unless omit_serializer?
24
+ generate_controller
25
+ generate_serializer
49
26
generate_application_resource unless application_resource_defined?
50
- generate_spec_payload unless omit_spec_payload?
51
- generate_strong_resource unless omit_strong_resource?
52
- generate_route unless omit_route?
53
- generate_tests unless omit_tests?
27
+ generate_spec_payload
28
+
29
+ if actions? ( 'create' , 'update' )
30
+ generate_strong_resource
31
+ end
32
+
33
+ generate_route
34
+ generate_tests
54
35
generate_resource
55
36
end
56
37
57
38
private
58
39
40
+ def actions
41
+ @options [ 'actions' ] || %w( index show create update destroy )
42
+ end
43
+
44
+ def actions? ( *methods )
45
+ methods . any? { |m | actions . include? ( m ) }
46
+ end
47
+
59
48
def omit_comments?
60
49
@options [ 'omit-comments' ]
61
50
end
@@ -65,19 +54,11 @@ def generate_controller
65
54
template ( 'controller.rb.erb' , to )
66
55
end
67
56
68
- def omit_controller?
69
- @options [ 'omit-controller' ]
70
- end
71
-
72
57
def generate_serializer
73
58
to = File . join ( 'app/serializers' , class_path , "serializable_#{ file_name } .rb" )
74
59
template ( 'serializer.rb.erb' , to )
75
60
end
76
61
77
- def omit_serializer?
78
- @options [ 'omit-serializer' ]
79
- end
80
-
81
62
def generate_application_resource
82
63
to = File . join ( 'app/resources' , class_path , "application_resource.rb" )
83
64
template ( 'application_resource.rb.erb' , to )
@@ -92,76 +73,103 @@ def generate_spec_payload
92
73
template ( 'payload.rb.erb' , to )
93
74
end
94
75
95
- def omit_spec_payload?
96
- @options [ 'no-payload' ]
97
- end
98
-
99
76
def generate_strong_resource
100
- code = <<-STR
101
- strong_resource : #{ file_name } do
102
- # Your attributes go here, e.g.
103
- # attribute :name, :string
104
- end
77
+ code = " strong_resource : #{ file_name } do \n "
78
+ attributes . each do | a |
79
+ code << " attribute : #{ a . name } , : #{ a . type } \n "
80
+ end
81
+ code << " end\n "
105
82
106
- STR
107
83
inject_into_file 'config/initializers/strong_resources.rb' , after : "StrongResources.configure do\n " do
108
84
code
109
85
end
110
86
end
111
87
112
- def omit_strong_resource?
113
- @options [ 'no-strong-resources' ]
114
- end
115
-
116
88
def generate_route
117
- code = <<-STR
118
- resources : #{ type }
119
- STR
89
+ code = " resources : #{ type } "
90
+ code << ", only: [ #{ actions . map { | a | ": #{ a } " } . join ( ', ' ) } ]" if actions . length < 5
91
+ code << " \n "
120
92
inject_into_file 'config/routes.rb' , after : "scope path: '/v1' do\n " do
121
93
code
122
94
end
123
95
end
124
96
125
- def omit_route?
126
- @options [ 'no-route' ]
127
- end
128
-
129
97
def generate_tests
130
- to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
131
- class_path ,
132
- "index_spec.rb"
133
- template ( 'index_request_spec.rb.erb' , to )
134
-
135
- to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
136
- class_path ,
137
- "show_spec.rb"
138
- template ( 'show_request_spec.rb.erb' , to )
98
+ if actions? ( 'index' )
99
+ to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
100
+ class_path ,
101
+ "index_spec.rb"
102
+ template ( 'index_request_spec.rb.erb' , to )
103
+ end
139
104
140
- to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
141
- class_path ,
142
- "create_spec.rb"
143
- template ( 'create_request_spec.rb.erb' , to )
105
+ if actions? ( 'show' )
106
+ to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
107
+ class_path ,
108
+ "show_spec.rb"
109
+ template ( 'show_request_spec.rb.erb' , to )
110
+ end
144
111
145
- to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
146
- class_path ,
147
- "update_spec.rb"
148
- template ( 'update_request_spec.rb.erb' , to )
112
+ if actions? ( 'create' )
113
+ to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
114
+ class_path ,
115
+ "create_spec.rb"
116
+ template ( 'create_request_spec.rb.erb' , to )
117
+ end
149
118
150
- to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
151
- class_path ,
152
- "destroy_spec.rb"
153
- template ( 'destroy_request_spec.rb.erb' , to )
154
- end
119
+ if actions? ( 'update' )
120
+ to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
121
+ class_path ,
122
+ "update_spec.rb"
123
+ template ( 'update_request_spec.rb.erb' , to )
124
+ end
155
125
156
- def omit_tests?
157
- @options [ 'no-test' ]
126
+ if actions? ( 'destroy' )
127
+ to = File . join "spec/api/v1/#{ file_name . pluralize } " ,
128
+ class_path ,
129
+ "destroy_spec.rb"
130
+ template ( 'destroy_request_spec.rb.erb' , to )
131
+ end
158
132
end
159
133
160
134
def generate_resource
161
135
to = File . join ( 'app/resources' , class_path , "#{ file_name } _resource.rb" )
162
136
template ( 'resource.rb.erb' , to )
163
137
end
164
138
139
+ def jsonapi_config
140
+ File . exists? ( '.jsonapicfg.yml' ) ? YAML . load_file ( '.jsonapicfg.yml' ) : { }
141
+ end
142
+
143
+ def update_config! ( attrs )
144
+ config = jsonapi_config . merge ( attrs )
145
+ File . open ( '.jsonapicfg.yml' , 'w' ) { |f | f . write ( config . to_yaml ) }
146
+ end
147
+
148
+ def prompt ( header : nil , description : nil , default : nil )
149
+ say ( set_color ( "\n #{ header } " , :magenta , :bold ) ) if header
150
+ say ( "\n #{ description } " ) if description
151
+ answer = ask ( set_color ( "\n (default: #{ default } ):" , :magenta , :bold ) )
152
+ answer = default if answer . blank? && default != 'nil'
153
+ say ( set_color ( "\n Got it!\n " , :white , :bold ) )
154
+ answer
155
+ end
156
+
157
+ def api_namespace
158
+ @api_namespace ||= begin
159
+ ns = jsonapi_config [ 'namespace' ]
160
+
161
+ if ns . blank?
162
+ ns = prompt \
163
+ header : "What is your API namespace?" ,
164
+ description : "This will be used as a route prefix, e.g. if you want the route '/books_api/v1/authors' your namespace would be 'books_api'" ,
165
+ default : 'api'
166
+ update_config! ( 'namespace' => ns )
167
+ end
168
+
169
+ ns
170
+ end
171
+ end
172
+
165
173
def model_klass
166
174
class_name . safe_constantize
167
175
end
0 commit comments