Refactoring
This commit is contained in:
parent
0048bd2c80
commit
7f27543081
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,8 +26,7 @@ pkg
|
|||||||
#*.tmproj
|
#*.tmproj
|
||||||
#tmtags
|
#tmtags
|
||||||
|
|
||||||
# For vim:
|
*.swp
|
||||||
#*.swp
|
|
||||||
|
|
||||||
# For redcar:
|
# For redcar:
|
||||||
#.redcar
|
#.redcar
|
||||||
|
|||||||
@ -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
|
||||||
|
return @reflected_record_type if defined?(@reflected_record_type)
|
||||||
|
|
||||||
|
@reflected_record_type ||= begin
|
||||||
if self.name.end_with?('Serializer')
|
if self.name.end_with?('Serializer')
|
||||||
class_name = self.name.demodulize
|
self.name.split('::').last.chomp('Serializer').underscore.to_sym
|
||||||
range_end = class_name.rindex('Serializer')
|
end
|
||||||
class_name[0...range_end].underscore.to_sym
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user