Refactoring
This commit is contained in:
parent
0048bd2c80
commit
7f27543081
3
.gitignore
vendored
3
.gitignore
vendored
@ -26,8 +26,7 @@ pkg
|
||||
#*.tmproj
|
||||
#tmtags
|
||||
|
||||
# For vim:
|
||||
#*.swp
|
||||
*.swp
|
||||
|
||||
# For redcar:
|
||||
#.redcar
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user