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 #*.tmproj
#tmtags #tmtags
# For vim: *.swp
#*.swp
# For redcar: # For redcar:
#.redcar #.redcar

View File

@ -30,47 +30,45 @@ module FastJsonapi
end end
# Set record_type based on the name of the serializer class # 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 end
def initialize(resource, options = {}) def initialize(resource, options = {})
if options.present? process_options(options)
@meta_tags = options[:meta]
@includes = options[:include].delete_if(&:blank?) if options[:include].present? @resource = resource
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
end end
def serializable_hash 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 = { data: nil }
serializable_hash[:meta] = @meta_tags if @meta_tags.present? serializable_hash[:meta] = @meta if @meta.present?
return hash_for_one_record(serializable_hash) if @record
return hash_for_multiple_records(serializable_hash) if @records 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 serializable_hash
end end
def hash_for_one_record(serializable_hash) def hash_for_collection
serializable_hash[:data] = self.class.record_hash(@record) serializable_hash = {}
serializable_hash[:included] = self.class.get_included_records(@record, @includes, @known_included_objects) if @includes.present?
serializable_hash
end
def hash_for_multiple_records(serializable_hash)
data = [] data = []
included = [] included = []
@records.each do |record| @resource.each do |record|
data << self.class.record_hash(record) data << self.class.record_hash(record)
included.concat self.class.get_included_records(record, @includes, @known_included_objects) if @includes.present? included.concat self.class.get_included_records(record, @includes, @known_included_objects) if @includes.present?
end end
serializable_hash[:data] = data serializable_hash[:data] = data
serializable_hash[:included] = included if @includes.present? serializable_hash[:included] = included if @includes.present?
serializable_hash[:meta] = @meta if @meta.present?
serializable_hash serializable_hash
end end
@ -78,23 +76,55 @@ module FastJsonapi
self.class.to_json(serializable_hash) self.class.to_json(serializable_hash)
end 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 class_methods do
def use_hyphen def use_hyphen
@hyphenated = true @hyphenated = true
end end
def set_type(type_name) def set_type(type)
self.record_type = type_name return unless type
if @hyphenated
self.record_type = type_name.to_s.dasherize.to_sym type = type.to_s.underscore
end type = type.dasherize if @hyphenated
self.record_type = type.to_sym
end end
def default_record_type def reflected_record_type
if self.name.end_with?('Serializer') return @reflected_record_type if defined?(@reflected_record_type)
class_name = self.name.demodulize
range_end = class_name.rindex('Serializer') @reflected_record_type ||= begin
class_name[0...range_end].underscore.to_sym if self.name.end_with?('Serializer')
self.name.split('::').last.chomp('Serializer').underscore.to_sym
end
end end
end end

View File

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