Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: dc7ef95bd0
Fetching contributors…

Cannot retrieve contributors at this time

file 139 lines (110 sloc) 3.157 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
require 'ixtlan/babel/hash_filter'
require 'ixtlan/babel/model_filter'
require 'ixtlan/babel/filter_config'
module Ixtlan
  module Babel
    class Serializer

      def id
        if @model_or_models.is_a? Array
          super
        else
          @model_or_models.id
        end
      end

      def initialize(model_or_models)
        @model_or_models = model_or_models
      end
      
      def respond_to?(method)
        @model_or_models.respond_to?(method)
      end

      def method_missing(method, *args, &block)
        @model_or_models.send(method, *args, &block)
      end
      
      def add_custom_serializers(map)
        filter.add_custom_serializers(map)
      end

      private

      def self.config
        @config ||= FilterConfig.new
      end

      def filter
        @filter ||= @model_or_models.is_a?( Hash ) ? HashFilter.new : ModelFilter.new
      end

      protected

      # for rails
      def self.model(model = nil)
        @model_class = model if model
        @model_class ||= self.to_s.sub(/Serializer$/, '').constantize
      end

      # for rails
      def self.model_name
        model.model_name
      end

      def self.default_context_key(single = :single, collection = :collection)
        config.default_context_key(single, collection)
      end

      def self.add_context(key, options = {})
        config[key] = options
      end

      def self.root( root )
        config.root = root
      end

      public

      def use( context_or_options )
        @context_or_options = context_or_options
        self
      end

      def to_hash(options = nil)
        setup_filter( options )
        if collection?
          @model_or_models.collect do |m|
            filter_model( m )
          end
        else
          filter_model( @model_or_models )
        end
      end

      def to_json(options = nil)
        to_hash(options).to_json
      end

      def setup_filter(options)
        o = if collection?
              self.class.config.collection_options( @context_or_options )
            else
              self.class.config.single_options( @context_or_options )
            end
        filter.options = o.merge!( options || {} )
        filter.options[:root] ||= self.class.config.root
      end
      private :setup_filter

      def collection?
        @is_collection ||= @model_or_models.respond_to?(:collect) && ! @model_or_models.is_a?(Hash)
      end
      private :collection?

      def to_xml(options = nil)
        setup_filter

        result = to_hash

        root = config.root

        if root && result.is_a?(Array) && root.respond_to?(:pluralize)
          root = root.pluralize
        end
        result.to_xml :root => root
      end

      def to_yaml(options = nil)
        to_hash(options).to_yaml
      end
      
      protected

      def attr(model)
        model.attributes if model
      end

      private

      def filter_model( model )
        if root = filter.options[:root]
          { root.to_s => filter.filter( model ){ |model| attr(model) } }
        else
          filter.filter( model ){ |model| attr(model) }
        end
      end
    end
  end
end
Something went wrong with that request. Please try again.