Skip to content

Commit 1a163a1

Browse files
authored
Add generators for (de)serializable models. (#2)
1 parent 1608026 commit 1a163a1

File tree

7 files changed

+149
-1
lines changed

7 files changed

+149
-1
lines changed

jsonapi-rails.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
1515
spec.files = Dir['README.md', 'lib/**/*']
1616
spec.require_path = 'lib'
1717

18-
spec.add_dependency 'jsonapi-deserializable', '~> 0.1'
18+
spec.add_dependency 'jsonapi-deserializable', '0.1.1.beta2'
1919
# because this gem is intended for rails use, active_support will
2020
# already be included
2121
spec.add_dependency 'activesupport', '> 4.0'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Description:
2+
Generates a deserializable resource for the given model.
3+
4+
Example:
5+
`rails generate jsonapi:deserializable User`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module Jsonapi
2+
class DeserializableGenerator < ::Rails::Generators::NamedBase
3+
source_root File.expand_path('../templates', __FILE__)
4+
5+
# TODO(beauby): Implement generator-level whitelisting.
6+
# TODO(beauby): Implement versioning.
7+
8+
def copy_deserializable_file
9+
template 'deserializable.rb.erb',
10+
File.join('app/deserializable', class_path,
11+
"deserializable_#{file_name}.rb")
12+
end
13+
14+
private
15+
16+
def model_klass
17+
# TODO(beauby): Ensure the model class exists.
18+
class_name.safe_constantize
19+
end
20+
21+
def attr_names
22+
attrs = model_klass.new.attribute_names - %w(id created_at updated_at)
23+
fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
24+
.map(&:foreign_key)
25+
attrs - fk_attrs
26+
end
27+
28+
def has_one_rels
29+
has_one = model_klass.reflect_on_all_associations(:has_one)
30+
belongs_to = model_klass.reflect_on_all_associations(:belongs_to)
31+
32+
has_one + belongs_to
33+
end
34+
35+
def has_one_id_field_name(rel_name)
36+
"#{rel_name}_id"
37+
end
38+
39+
def has_one_type_field_name(rel_name)
40+
"#{rel_name}_type"
41+
end
42+
43+
def has_many_rels
44+
model_klass.reflect_on_all_associations(:has_many)
45+
end
46+
47+
def has_many_id_field_name(rel_name)
48+
"#{rel_name.to_s.singularize}_ids"
49+
end
50+
51+
def has_many_type_field_name(rel_name)
52+
"#{rel_name.to_s.singularize}_types"
53+
end
54+
end
55+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<% module_namespacing do -%>
2+
class Deserializable<%= class_name %> < JSONAPI::Deserializable::Resource
3+
id
4+
5+
<% attr_names.each do |attr| -%>
6+
attribute :<%= attr %>
7+
<% end -%>
8+
9+
<% has_one_rels.each do |reflection| -%>
10+
has_one :<%= reflection.name %> do |rel, id, type|
11+
field <%= has_one_id_field_name(reflection.name) %>: id
12+
<% if reflection.polymorphic? -%>
13+
field <%= has_one_type_field_name(reflection.name) %>: type
14+
<% end -%>
15+
end
16+
<% end -%>
17+
<% has_many_rels.each do |reflection| -%>
18+
has_many :<%= reflection.name %> do |rel, ids, types|
19+
field <%= has_many_id_field_name(reflection.name) %>: ids
20+
<% if reflection.polymorphic? -%>
21+
field <%= has_one_type_field_name(reflection.name) %>: types
22+
<% end -%>
23+
end
24+
<% end -%>
25+
end
26+
<% end -%>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Description:
2+
Generates a serializable resource for the given model.
3+
4+
Example:
5+
`rails generate jsonapi:serializable User`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
module Jsonapi
2+
class SerializableGenerator < ::Rails::Generators::NamedBase
3+
source_root File.expand_path('../templates', __FILE__)
4+
5+
# TODO(beauby): Implement generator-level whitelisting.
6+
# TODO(beauby): Implement versioning.
7+
8+
def copy_serializable_file
9+
template 'serializable.rb.erb',
10+
File.join('app/serializable', class_path,
11+
"serializable_#{file_name}.rb")
12+
end
13+
14+
private
15+
16+
def model_klass
17+
# TODO(beauby): Ensure the model class exists.
18+
class_name.safe_constantize
19+
end
20+
21+
def type
22+
model_klass.name.underscore.pluralize
23+
end
24+
25+
def attr_names
26+
attrs = model_klass.new.attribute_names - ['id']
27+
fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
28+
.map(&:foreign_key)
29+
attrs - fk_attrs
30+
end
31+
32+
def has_one_rel_names
33+
model_klass.reflect_on_all_associations(:has_one).map(&:name) +
34+
model_klass.reflect_on_all_associations(:belongs_to).map(&:name)
35+
end
36+
37+
def has_many_rel_names
38+
model_klass.reflect_on_all_associations(:has_many).map(&:name)
39+
end
40+
end
41+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<% module_namespacing do -%>
2+
class Serializable<%= class_name %> < JSONAPI::Serializable::Model
3+
type '<%= type %>'
4+
5+
<% attr_names.each do |attr| -%>
6+
attribute :<%= attr %>
7+
<% end -%>
8+
9+
<% has_one_rel_names.each do |rel| -%>
10+
has_one :<%= rel %>
11+
<% end -%>
12+
<% has_many_rel_names.each do |rel| -%>
13+
has_many :<%= rel %>
14+
<% end -%>
15+
end
16+
<% end -%>

0 commit comments

Comments
 (0)