mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-23 06:16:50 +00:00
172 lines
4.9 KiB
Ruby
172 lines
4.9 KiB
Ruby
require 'thread_safe'
|
|
|
|
module ActiveModel
|
|
class Serializer
|
|
extend ActiveSupport::Autoload
|
|
|
|
autoload :Configuration
|
|
autoload :ArraySerializer
|
|
autoload :Adapter
|
|
autoload :Lint
|
|
autoload :Associations
|
|
autoload :Fieldset
|
|
autoload :Utils
|
|
include Configuration
|
|
include Associations
|
|
|
|
# Matches
|
|
# "c:/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `<top (required)>'"
|
|
# AND
|
|
# "/c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb:1:in `<top (required)>'"
|
|
# AS
|
|
# c/git/emberjs/ember-crm-backend/app/serializers/lead_serializer.rb
|
|
CALLER_FILE = /
|
|
\A # start of string
|
|
\S+ # one or more non-spaces
|
|
(?= # stop previous match when
|
|
:\d+ # a colon is followed by one or more digits
|
|
:in # followed by a colon followed by in
|
|
)
|
|
/x
|
|
|
|
class << self
|
|
attr_accessor :_attributes
|
|
attr_accessor :_attributes_keys
|
|
attr_accessor :_cache
|
|
attr_accessor :_fragmented
|
|
attr_accessor :_cache_key
|
|
attr_accessor :_cache_only
|
|
attr_accessor :_cache_except
|
|
attr_accessor :_cache_options
|
|
attr_accessor :_cache_digest
|
|
end
|
|
|
|
def self.inherited(base)
|
|
base._attributes = _attributes.try(:dup) || []
|
|
base._attributes_keys = _attributes_keys.try(:dup) || {}
|
|
base._cache_digest = digest_caller_file(caller.first)
|
|
super
|
|
end
|
|
|
|
def self.attributes(*attrs)
|
|
attrs = attrs.first if attrs.first.class == Array
|
|
|
|
attrs.each do |attr|
|
|
attribute(attr)
|
|
end
|
|
end
|
|
|
|
def self.attribute(attr, options = {})
|
|
key = options.fetch(:key, attr)
|
|
_attributes_keys[attr] = { key: key } if key != attr
|
|
_attributes << key unless _attributes.include?(key)
|
|
|
|
ActiveModelSerializers.silence_warnings do
|
|
define_method key do
|
|
object.read_attribute_for_serialization(attr)
|
|
end unless (key != :id && method_defined?(key)) || _fragmented.respond_to?(attr)
|
|
end
|
|
end
|
|
|
|
def self.fragmented(serializer)
|
|
self._fragmented = serializer
|
|
end
|
|
|
|
# Enables a serializer to be automatically cached
|
|
def self.cache(options = {})
|
|
self._cache = ActionController::Base.cache_store if Rails.configuration.action_controller.perform_caching
|
|
self._cache_key = options.delete(:key)
|
|
self._cache_only = options.delete(:only)
|
|
self._cache_except = options.delete(:except)
|
|
self._cache_options = (options.empty?) ? nil : options
|
|
end
|
|
|
|
def self.serializer_for(resource, options = {})
|
|
if resource.respond_to?(:serializer_class)
|
|
resource.serializer_class
|
|
elsif resource.respond_to?(:to_ary)
|
|
config.array_serializer
|
|
else
|
|
options.fetch(:serializer) { get_serializer_for(resource.class) }
|
|
end
|
|
end
|
|
|
|
# @see ActiveModel::Serializer::Adapter.lookup
|
|
def self.adapter
|
|
ActiveModel::Serializer::Adapter.lookup(config.adapter)
|
|
end
|
|
|
|
def self.root_name
|
|
name.demodulize.underscore.sub(/_serializer$/, '') if name
|
|
end
|
|
|
|
def self.serializers_cache
|
|
@serializers_cache ||= ThreadSafe::Cache.new
|
|
end
|
|
|
|
def self.digest_caller_file(caller_line)
|
|
serializer_file_path = caller_line[CALLER_FILE]
|
|
serializer_file_contents = IO.read(serializer_file_path)
|
|
Digest::MD5.hexdigest(serializer_file_contents)
|
|
end
|
|
|
|
def self.get_serializer_for(klass)
|
|
serializers_cache.fetch_or_store(klass) do
|
|
serializer_class_name = "#{klass.name}Serializer"
|
|
serializer_class = serializer_class_name.safe_constantize
|
|
|
|
if serializer_class
|
|
serializer_class
|
|
elsif klass.superclass
|
|
get_serializer_for(klass.superclass)
|
|
end
|
|
end
|
|
end
|
|
|
|
attr_accessor :object, :root, :meta, :meta_key, :scope
|
|
|
|
def initialize(object, options = {})
|
|
self.object = object
|
|
self.instance_options = options
|
|
self.root = instance_options[:root]
|
|
self.meta = instance_options[:meta]
|
|
self.meta_key = instance_options[:meta_key]
|
|
self.scope = instance_options[:scope]
|
|
|
|
scope_name = instance_options[:scope_name]
|
|
if scope_name && !respond_to?(scope_name)
|
|
self.class.class_eval do
|
|
define_method scope_name, lambda { scope }
|
|
end
|
|
end
|
|
end
|
|
|
|
def json_key
|
|
root || object.class.model_name.to_s.underscore
|
|
end
|
|
|
|
def attributes(options = {})
|
|
attributes =
|
|
if options[:fields]
|
|
self.class._attributes & options[:fields]
|
|
else
|
|
self.class._attributes.dup
|
|
end
|
|
|
|
attributes.each_with_object({}) do |name, hash|
|
|
unless self.class._fragmented
|
|
hash[name] = send(name)
|
|
else
|
|
hash[name] = self.class._fragmented.public_send(name)
|
|
end
|
|
end
|
|
end
|
|
|
|
private # rubocop:disable Lint/UselessAccessModifier
|
|
|
|
ActiveModelSerializers.silence_warnings do
|
|
attr_accessor :instance_options
|
|
end
|
|
end
|
|
end
|