Skip to content

Add generators for (de)serializable models. #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion jsonapi-rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
spec.files = Dir['README.md', 'lib/**/*']
spec.require_path = 'lib'

spec.add_dependency 'jsonapi-deserializable', '~> 0.1'
spec.add_dependency 'jsonapi-deserializable', '0.1.1.beta2'
# because this gem is intended for rails use, active_support will
# already be included
spec.add_dependency 'activesupport', '> 4.0'
Expand Down
5 changes: 5 additions & 0 deletions lib/generators/jsonapi/deserializable/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Description:
Generates a deserializable resource for the given model.

Example:
`rails generate jsonapi:deserializable User`
55 changes: 55 additions & 0 deletions lib/generators/jsonapi/deserializable/deserializable_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module Jsonapi
class DeserializableGenerator < ::Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)

# TODO(beauby): Implement generator-level whitelisting.
# TODO(beauby): Implement versioning.

def copy_deserializable_file
template 'deserializable.rb.erb',
File.join('app/deserializable', class_path,
"deserializable_#{file_name}.rb")
end

private

def model_klass
# TODO(beauby): Ensure the model class exists.
class_name.safe_constantize
end

def attr_names
attrs = model_klass.new.attribute_names - %w(id created_at updated_at)
fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
.map(&:foreign_key)
attrs - fk_attrs
end

def has_one_rels
has_one = model_klass.reflect_on_all_associations(:has_one)
belongs_to = model_klass.reflect_on_all_associations(:belongs_to)

has_one + belongs_to
end

def has_one_id_field_name(rel_name)
"#{rel_name}_id"
end

def has_one_type_field_name(rel_name)
"#{rel_name}_type"
end

def has_many_rels
model_klass.reflect_on_all_associations(:has_many)
end

def has_many_id_field_name(rel_name)
"#{rel_name.to_s.singularize}_ids"
end

def has_many_type_field_name(rel_name)
"#{rel_name.to_s.singularize}_types"
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<% module_namespacing do -%>
class Deserializable<%= class_name %> < JSONAPI::Deserializable::Resource
id

<% attr_names.each do |attr| -%>
attribute :<%= attr %>
<% end -%>

<% has_one_rels.each do |reflection| -%>
has_one :<%= reflection.name %> do |rel, id, type|
field <%= has_one_id_field_name(reflection.name) %>: id
<% if reflection.polymorphic? -%>
field <%= has_one_type_field_name(reflection.name) %>: type
<% end -%>
end
<% end -%>
<% has_many_rels.each do |reflection| -%>
has_many :<%= reflection.name %> do |rel, ids, types|
field <%= has_many_id_field_name(reflection.name) %>: ids
<% if reflection.polymorphic? -%>
field <%= has_one_type_field_name(reflection.name) %>: types
<% end -%>
end
<% end -%>
end
<% end -%>
5 changes: 5 additions & 0 deletions lib/generators/jsonapi/serializable/USAGE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Description:
Generates a serializable resource for the given model.

Example:
`rails generate jsonapi:serializable User`
41 changes: 41 additions & 0 deletions lib/generators/jsonapi/serializable/serializable_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module Jsonapi
class SerializableGenerator < ::Rails::Generators::NamedBase
source_root File.expand_path('../templates', __FILE__)

# TODO(beauby): Implement generator-level whitelisting.
# TODO(beauby): Implement versioning.

def copy_serializable_file
template 'serializable.rb.erb',
File.join('app/serializable', class_path,
"serializable_#{file_name}.rb")
end

private

def model_klass
# TODO(beauby): Ensure the model class exists.
class_name.safe_constantize
end

def type
model_klass.name.underscore.pluralize
end

def attr_names
attrs = model_klass.new.attribute_names - ['id']
fk_attrs = model_klass.reflect_on_all_associations(:belongs_to)
.map(&:foreign_key)
attrs - fk_attrs
end

def has_one_rel_names
model_klass.reflect_on_all_associations(:has_one).map(&:name) +
model_klass.reflect_on_all_associations(:belongs_to).map(&:name)
end

def has_many_rel_names
model_klass.reflect_on_all_associations(:has_many).map(&:name)
end
end
end
16 changes: 16 additions & 0 deletions lib/generators/jsonapi/serializable/templates/serializable.rb.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<% module_namespacing do -%>
class Serializable<%= class_name %> < JSONAPI::Serializable::Model
type '<%= type %>'

<% attr_names.each do |attr| -%>
attribute :<%= attr %>
<% end -%>

<% has_one_rel_names.each do |rel| -%>
has_one :<%= rel %>
<% end -%>
<% has_many_rel_names.each do |rel| -%>
has_many :<%= rel %>
<% end -%>
end
<% end -%>