diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 789cfd56..714ff65d 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -8,6 +8,8 @@ require 'active_model/serializer/caching' require 'active_model/serializer/configuration' require 'active_model/serializer/fieldset' require 'active_model/serializer/lint' +require 'active_model/serializer/links' +require 'active_model/serializer/type' # ActiveModel::Serializer is an abstract class that is # reified when subclassed to decorate a resource. @@ -17,32 +19,10 @@ module ActiveModel include Associations include Attributes include Caching + include Links + include Type require 'active_model/serializer/adapter' - with_options instance_writer: false, instance_reader: false do |serializer| - serializer.class_attribute :_type, instance_reader: true - serializer.class_attribute :_links # @api private : links definitions, @see Serializer#link - self._links ||= {} - end - - # Serializers inherit _attribute_mappings, _reflections, and _links. - # Generates a unique digest for each serializer at load. - def self.inherited(base) - base._links = _links.dup - super - end - - # @example - # class AdminAuthorSerializer < ActiveModel::Serializer - # type 'authors' - def self.type(type) - self._type = type - end - - def self.link(name, value = nil, &block) - _links[name] = block || value - end - # @param resource [ActiveRecord::Base, ActiveModelSerializers::Model] # @return [ActiveModel::Serializer] # Preferentially returns @@ -148,12 +128,6 @@ module ActiveModel end end - # @api private - # Used by JsonApi adapter to build resource links. - def links - self.class._links - end - protected attr_accessor :instance_options diff --git a/lib/active_model/serializer/adapter/json_api.rb b/lib/active_model/serializer/adapter/json_api.rb index 1c7f7226..c236c3d3 100644 --- a/lib/active_model/serializer/adapter/json_api.rb +++ b/lib/active_model/serializer/adapter/json_api.rb @@ -208,7 +208,7 @@ module ActiveModel end def links_for(serializer) - serializer.links.each_with_object({}) do |(name, value), hash| + serializer._links.each_with_object({}) do |(name, value), hash| hash[name] = if value.respond_to?(:call) link = Link.new(serializer) diff --git a/lib/active_model/serializer/links.rb b/lib/active_model/serializer/links.rb new file mode 100644 index 00000000..1df77261 --- /dev/null +++ b/lib/active_model/serializer/links.rb @@ -0,0 +1,33 @@ +module ActiveModel + class Serializer + module Links + extend ActiveSupport::Concern + + included do + with_options instance_writer: false, instance_reader: true do |serializer| + serializer.class_attribute :_links # @api private + self._links ||= {} + end + + extend ActiveSupport::Autoload + end + + module ClassMethods + def inherited(base) + super + base._links = _links.dup + end + + # Define a link on a serializer. + # @example + # link :self { "/posts/#{object.id}" } + # @example + # link :self, "/user" + # + def link(name, value = nil, &block) + _links[name] = block || value + end + end + end + end +end diff --git a/lib/active_model/serializer/type.rb b/lib/active_model/serializer/type.rb new file mode 100644 index 00000000..563cb694 --- /dev/null +++ b/lib/active_model/serializer/type.rb @@ -0,0 +1,25 @@ +module ActiveModel + class Serializer + module Type + extend ActiveSupport::Concern + + included do + with_options instance_writer: false, instance_reader: true do |serializer| + serializer.class_attribute :_type # @api private + end + + extend ActiveSupport::Autoload + end + + module ClassMethods + # Set the JSON API type of a serializer. + # @example + # class AdminAuthorSerializer < ActiveModel::Serializer + # type 'authors' + def type(type) + self._type = type + end + end + end + end +end