Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add Serializer#schema #1430

Open
bf4 opened this issue Jan 13, 2016 · 1 comment
Open

Re-add Serializer#schema #1430

bf4 opened this issue Jan 13, 2016 · 1 comment

Comments

@bf4
Copy link
Member

bf4 commented Jan 13, 2016

Was a nice feature in 0.8.x that could be useful with #1162 and #1270

     # Return a schema hash for the current serializer. This information
      # can be used to generate clients for the serialized output.
      #
      # The schema hash has two keys: +attributes+ and +associations+.
      #
      # The +attributes+ hash looks like this:
      #
      #     { :name => :string, :age => :integer }
      #
      # The +associations+ hash looks like this:
      #     { :posts => { :has_many => :posts } }
      #
      # If :key is used:
      #
      #     class PostsSerializer < ActiveModel::Serializer
      #       has_many :posts, :key => :my_posts
      #     end
      #
      # the hash looks like this:
      #
      #     { :my_posts => { :has_many => :posts }
      #
      # This information is extracted from the serializer's model class,
      # which is provided by +SerializerClass.model_class+.
      #
      # The schema method uses the +columns_hash+ and +reflect_on_association+
      # methods, provided by default by ActiveRecord. You can implement these
      # methods on your custom models if you want the serializer's schema method
      # to work.
      #
      # TODO: This is currently coupled to Active Record. We need to
      # figure out a way to decouple those two.
      def schema
        klass = model_class
        columns = klass.columns_hash

        attrs = {}
        _attributes.each do |name, key|
          if column = columns[name.to_s]
            attrs[key] = column.type
          else
            # Computed attribute (method on serializer or model). We cannot
            # infer the type, so we put nil, unless specified in the attribute declaration
            if name != key
              attrs[name] = key
            else
              attrs[key] = nil
            end
          end
        end

        associations = {}
        _associations.each do |attr, association_class|
          association = association_class.new(attr, self)

          if model_association = klass.reflect_on_association(association.name)
            # Real association.
            associations[association.key] = { model_association.macro => model_association.name }
          else
            # Computed association. We could infer has_many vs. has_one from
            # the association class, but that would make it different from
            # real associations, which read has_one vs. belongs_to from the
            # model.
            associations[association.key] = nil
          end
        end

        { :attributes => attrs, :associations => associations }
      end

      # The model class associated with this serializer.
      def model_class
        name.sub(/Serializer$/, '').constantize
      end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants