Refactoring

This commit is contained in:
Sergii Makagon 2018-02-04 15:41:03 -05:00 committed by Shishir Kakaraddi
parent 0048bd2c80
commit 7f27543081
4 changed files with 66 additions and 53 deletions

3
.gitignore vendored
View File

@ -26,8 +26,7 @@ pkg
#*.tmproj
#tmtags
# For vim:
#*.swp
*.swp
# For redcar:
#.redcar

View File

@ -30,47 +30,45 @@ module FastJsonapi
end
# Set record_type based on the name of the serializer class
set_type default_record_type if default_record_type
set_type(reflected_record_type) if reflected_record_type
end
def initialize(resource, options = {})
if options.present?
@meta_tags = options[:meta]
@includes = options[:include].delete_if(&:blank?) if options[:include].present?
self.class.has_permitted_includes(@includes) if @includes.present?
@known_included_objects = {} # keep track of inc objects that have already been serialized
end
# @records if enumerables like Array, ActiveRecord::Relation but if Struct just make it a @record
if resource.respond_to?(:each) && !resource.respond_to?(:each_pair)
@records = resource
else
@record = resource
end
process_options(options)
@resource = resource
end
def serializable_hash
return hash_for_collection if is_collection?(@resource)
hash_for_one_record
end
def hash_for_one_record
serializable_hash = { data: nil }
serializable_hash[:meta] = @meta_tags if @meta_tags.present?
return hash_for_one_record(serializable_hash) if @record
return hash_for_multiple_records(serializable_hash) if @records
serializable_hash[:meta] = @meta if @meta.present?
return serializable_hash unless @resource
serializable_hash[:data] = self.class.record_hash(@resource)
serializable_hash[:included] = self.class.get_included_records(@resource, @includes, @known_included_objects) if @includes.present?
serializable_hash
end
def hash_for_one_record(serializable_hash)
serializable_hash[:data] = self.class.record_hash(@record)
serializable_hash[:included] = self.class.get_included_records(@record, @includes, @known_included_objects) if @includes.present?
serializable_hash
end
def hash_for_collection
serializable_hash = {}
def hash_for_multiple_records(serializable_hash)
data = []
included = []
@records.each do |record|
@resource.each do |record|
data << self.class.record_hash(record)
included.concat self.class.get_included_records(record, @includes, @known_included_objects) if @includes.present?
end
serializable_hash[:data] = data
serializable_hash[:included] = included if @includes.present?
serializable_hash[:meta] = @meta if @meta.present?
serializable_hash
end
@ -78,23 +76,55 @@ module FastJsonapi
self.class.to_json(serializable_hash)
end
private
def process_options(options)
return if options.blank?
@known_included_objects = {}
@meta = options[:meta]
if options[:include].present?
@includes = options[:include].delete_if(&:blank?)
validate_includes!(@includes)
end
end
def validate_includes!(includes)
return if includes.blank?
existing_relationships = self.class.relationships_to_serialize.keys.to_set
unless existing_relationships.superset?(includes.to_set)
raise ArgumentError, "One of keys from #{includes} is not specified as a relationship on the serializer"
end
end
def is_collection?(resource)
resource.respond_to?(:each) && !resource.respond_to?(:each_pair)
end
class_methods do
def use_hyphen
@hyphenated = true
end
def set_type(type_name)
self.record_type = type_name
if @hyphenated
self.record_type = type_name.to_s.dasherize.to_sym
end
def set_type(type)
return unless type
type = type.to_s.underscore
type = type.dasherize if @hyphenated
self.record_type = type.to_sym
end
def default_record_type
if self.name.end_with?('Serializer')
class_name = self.name.demodulize
range_end = class_name.rindex('Serializer')
class_name[0...range_end].underscore.to_sym
def reflected_record_type
return @reflected_record_type if defined?(@reflected_record_type)
@reflected_record_type ||= begin
if self.name.end_with?('Serializer')
self.name.split('::').last.chomp('Serializer').underscore.to_sym
end
end
end

View File

@ -88,17 +88,6 @@ module FastJsonapi
end
end
end
def has_permitted_includes(requested_includes)
# requested includes should be within relationships defined on serializer
allowed_includes = @relationships_to_serialize.keys
intersection = allowed_includes & requested_includes
if intersection.sort == requested_includes.sort
true
else
raise ArgumentError, "One of keys from #{requested_includes} is not specified as a relationship on the serializer"
end
end
end
end
end

View File

@ -123,9 +123,7 @@ RSpec.shared_context 'movie class' do
:id, :name, :release_year, :actor_ids, :actors, :owner_id, :owner, :movie_type_id
)
ActorStruct = Struct.new(
:id, :name, :email
)
ActorStruct = Struct.new(:id, :name, :email)
end
after(:context) do
@ -151,10 +149,7 @@ RSpec.shared_context 'movie class' do
actors = []
3.times.each do |id|
a = ActorStruct.new
a[:id] = id
a[:name] = id.to_s
actors << a
actors << ActorStruct.new(id, id.to_s, id.to_s)
end
m = MovieStruct.new