active_model_serializers_rails_2.3 0.9.0.alpha1 → 0.9.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +11 -55
- data/lib/active_model/array_serializer.rb +9 -34
- data/lib/active_model/as_json_overrides.rb +6 -0
- data/lib/active_model/default_serializer.rb +3 -12
- data/lib/active_model/serializable.rb +5 -9
- data/lib/active_model/serializer/associations.rb +15 -53
- data/lib/active_model/serializer/railtie.rb +2 -2
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model/serializer.rb +29 -56
- data/lib/active_model_serializers.rb +2 -18
- data/test/coverage_setup.rb +9 -12
- data/test/fixtures/active_record.rb +3 -3
- data/test/integration/active_record/active_record_test.rb +21 -23
- data/test/test_app.rb +1 -4
- data/test/test_helper.rb +0 -3
- data/test/unit/active_model/array_serializer/meta_test.rb +1 -1
- data/test/unit/active_model/array_serializer/root_test.rb +2 -2
- data/test/unit/active_model/array_serializer/scope_test.rb +1 -1
- data/test/unit/active_model/array_serializer/serialize_test.rb +45 -0
- data/test/unit/active_model/default_serializer_test.rb +6 -4
- data/test/unit/active_model/serializer/attributes_test.rb +1 -13
- data/test/unit/active_model/serializer/config_test.rb +5 -5
- data/test/unit/active_model/serializer/filter_test.rb +2 -2
- data/test/unit/active_model/serializer/has_many_test.rb +6 -30
- data/test/unit/active_model/serializer/has_one_test.rb +5 -19
- data/test/unit/active_model/serializer/meta_test.rb +1 -1
- data/test/unit/active_model/serializer/root_test.rb +2 -16
- data/test/unit/active_model/serializer/scope_test.rb +1 -29
- metadata +11 -21
- data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +0 -14
- data/lib/active_model/serializer/generators/serializer/templates/controller.rb +0 -93
- data/test/unit/active_model/array_serializer/serialization_test.rb +0 -182
- data/test/unit/active_model/serializer/associations/build_serializer_test.rb +0 -21
- data/test/unit/active_model/serializer/associations_test.rb +0 -19
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 0bf1627e3e77f67d91a472d7973d66c3a8ca726b
         | 
| 4 | 
            +
              data.tar.gz: 905a98aa09e0e84a9ae4b0931f55d39fe1e0b8cd
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 3984baa7ec037bd7e4faf376127623bafac0b8de7fbb08f48e1effab5240968bce85a217104be9c55ad84204f170cc27860aa53b627a7a9eb8d034222a0b9048
         | 
| 7 | 
            +
              data.tar.gz: c4607f4816f99fd7d913a881937d0a6814482376e404877bd71bcc1db494b395058a70cb7a177f0fb92774ec56fef586db293cb830cebd9060c518f8dbb5b35c
         | 
    
        data/README.md
    CHANGED
    
    | @@ -10,19 +10,9 @@ This is a backport of the ActiveModel::Serializers gem to be compatible with | |
| 10 10 | 
             
            Rails 2.3. The following features have been removed:
         | 
| 11 11 |  | 
| 12 12 | 
             
            * Controller `render` method support. This means you'll need to instantiate
         | 
| 13 | 
            -
            the serializer yourself and pass it to `render`. E.g. `render :json => FooSerializer.new(foo | 
| 13 | 
            +
            the serializer yourself and pass it to `render`. E.g. `render :json => FooSerializer.new(foo)`
         | 
| 14 | 
            +
            * `current_user` and such support. Might be baked in later.
         | 
| 14 15 | 
             
            * Generators are gone as well.
         | 
| 15 | 
            -
            * Probably won't be supported for a long amount of time. Please do your best to upgrade
         | 
| 16 | 
            -
            to rails 3.2+ as soon as possible. Feel free to open an issue whenever I run
         | 
| 17 | 
            -
            too far behind upstream's master branch.
         | 
| 18 | 
            -
             | 
| 19 | 
            -
            ## Rails 2-3- 0.9.0
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            **Rails 2-3 is under development, there are some incompatible changes with the current stable release.**
         | 
| 22 | 
            -
             | 
| 23 | 
            -
            Since `0.8` there is no `options` accessor in the serializers. Some issues and pull-requests are attemps to bring back the ability to use Rails url helpers in the serializers, but nothing is really settled yet.
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            If you want to read the stable documentation visit [0.8 README](https://github.com/rails-api/active_model_serializers/blob/0-8-stable/README.md)
         | 
| 26 16 |  | 
| 27 17 | 
             
            ## Purpose
         | 
| 28 18 |  | 
| @@ -43,7 +33,7 @@ The easiest way to install `ActiveModel::Serializers` is to add it to your | |
| 43 33 | 
             
            `Gemfile`:
         | 
| 44 34 |  | 
| 45 35 | 
             
            ```ruby
         | 
| 46 | 
            -
            gem "active_model_serializers_rails2.3" | 
| 36 | 
            +
            gem "active_model_serializers_rails2.3"
         | 
| 47 37 | 
             
            ```
         | 
| 48 38 |  | 
| 49 39 | 
             
            Then, install it on the command line:
         | 
| @@ -85,6 +75,10 @@ Currently `ActiveModel::Serializers` expects objects to implement | |
| 85 75 | 
             
            read\_attribute\_for\_serialization. That's all you need to do to have
         | 
| 86 76 | 
             
            your POROs supported. 
         | 
| 87 77 |  | 
| 78 | 
            +
            # ActiveModel::Serializer
         | 
| 79 | 
            +
             | 
| 80 | 
            +
            All new serializers descend from ActiveModel::Serializer
         | 
| 81 | 
            +
             | 
| 88 82 | 
             
            # render :json
         | 
| 89 83 |  | 
| 90 84 | 
             
            In your controllers, when you use `render :json`, Rails will now first search
         | 
| @@ -168,20 +162,6 @@ To specify a custom serializer for the items within an array: | |
| 168 162 | 
             
            render json: @posts, each_serializer: FancyPostSerializer
         | 
| 169 163 | 
             
            ```
         | 
| 170 164 |  | 
| 171 | 
            -
            ## Render independently
         | 
| 172 | 
            -
             | 
| 173 | 
            -
            By default the setting of serializer is in controller as described above which is the
         | 
| 174 | 
            -
            recommeneded way. However, there may be cases you need to render the json object elsewhere
         | 
| 175 | 
            -
            say in a helper or a view when controller is only for main object.
         | 
| 176 | 
            -
             | 
| 177 | 
            -
            Then you can render the serialized JSON independently.
         | 
| 178 | 
            -
             | 
| 179 | 
            -
            ```ruby
         | 
| 180 | 
            -
            def current_user_as_json_helper
         | 
| 181 | 
            -
              CurrentUserSerializer.new(current_user).to_json
         | 
| 182 | 
            -
            end
         | 
| 183 | 
            -
            ```
         | 
| 184 | 
            -
             | 
| 185 165 | 
             
            ## Disabling the root element
         | 
| 186 166 |  | 
| 187 167 | 
             
            You have 4 options to disable the root element, each with a slightly different scope:
         | 
| @@ -287,9 +267,9 @@ authorization context to your serializer. By default, the context | |
| 287 267 | 
             
            is the current user of your application, but this
         | 
| 288 268 | 
             
            [can be customized](#customizing-scope).
         | 
| 289 269 |  | 
| 290 | 
            -
            Serializers provides a method named `filter | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 270 | 
            +
            Serializers provides a method named `filter` used to determine what
         | 
| 271 | 
            +
            attributes and associations should be included in the output. This is
         | 
| 272 | 
            +
            typically used to customize output based on `current_user`. For example:
         | 
| 293 273 |  | 
| 294 274 | 
             
            ```ruby
         | 
| 295 275 | 
             
            class PostSerializer < ActiveModel::Serializer
         | 
| @@ -306,8 +286,7 @@ end | |
| 306 286 | 
             
            ```
         | 
| 307 287 |  | 
| 308 288 | 
             
            And it's also safe to mutate keys argument by doing keys.delete(:author)
         | 
| 309 | 
            -
            in case you want to avoid creating two extra arrays. | 
| 310 | 
            -
            in-place modification, you still need to return the modified array.
         | 
| 289 | 
            +
            in case you want to avoid creating two extra arrays.
         | 
| 311 290 |  | 
| 312 291 | 
             
            If you would like the key in the outputted JSON to be different from its name
         | 
| 313 292 | 
             
            in ActiveRecord, you can declare the attribute with the different name
         | 
| @@ -748,29 +727,6 @@ end | |
| 748 727 |  | 
| 749 728 | 
             
            The caching interface uses `Rails.cache` under the hood.
         | 
| 750 729 |  | 
| 751 | 
            -
            # ApplicationSerializer
         | 
| 752 | 
            -
             | 
| 753 | 
            -
            By default, new serializers descend from ActiveModel::Serializer. However, if you wish to share behaviour across your serializers you can create an ApplicationSerializer at ```app/serializers/application_serializer.rb```:
         | 
| 754 | 
            -
             | 
| 755 | 
            -
            ```ruby
         | 
| 756 | 
            -
            class ApplicationSerializer < ActiveModel::Serializer
         | 
| 757 | 
            -
            end
         | 
| 758 | 
            -
            ```
         | 
| 759 | 
            -
             | 
| 760 | 
            -
            Any newly generated serializers will automatically descend from ApplicationSerializer.
         | 
| 761 | 
            -
             | 
| 762 | 
            -
            ```
         | 
| 763 | 
            -
            $ rails g serializer post
         | 
| 764 | 
            -
            ```
         | 
| 765 | 
            -
             | 
| 766 | 
            -
            now generates:
         | 
| 767 | 
            -
             | 
| 768 | 
            -
            ```ruby
         | 
| 769 | 
            -
            class PostSerializer < ApplicationSerializer
         | 
| 770 | 
            -
              attributes :id
         | 
| 771 | 
            -
            end
         | 
| 772 | 
            -
            ````
         | 
| 773 | 
            -
             | 
| 774 730 | 
             
            # Design and Implementation Guidelines
         | 
| 775 731 |  | 
| 776 732 | 
             
            ## Keep it Simple
         | 
| @@ -14,47 +14,22 @@ module ActiveModel | |
| 14 14 |  | 
| 15 15 | 
             
                def initialize(object, options={})
         | 
| 16 16 | 
             
                  @object          = object
         | 
| 17 | 
            -
                  @ | 
| 18 | 
            -
                  @root            =  | 
| 17 | 
            +
                  @root            = options[:root]
         | 
| 18 | 
            +
                  @root            = self.class._root if @root.nil?
         | 
| 19 | 
            +
                  @root            = options[:resource_name] if @root.nil?
         | 
| 19 20 | 
             
                  @meta_key        = options[:meta_key] || :meta
         | 
| 20 21 | 
             
                  @meta            = options[@meta_key]
         | 
| 21 22 | 
             
                  @each_serializer = options[:each_serializer]
         | 
| 22 | 
            -
                  @ | 
| 23 | 
            +
                  @options         = options.merge(root: nil)
         | 
| 23 24 | 
             
                end
         | 
| 24 | 
            -
                attr_accessor :object, : | 
| 25 | 
            +
                attr_accessor :object, :root, :meta_key, :meta
         | 
| 25 26 |  | 
| 26 | 
            -
                def  | 
| 27 | 
            -
                  if root.nil?
         | 
| 28 | 
            -
                    @resource_name
         | 
| 29 | 
            -
                  else
         | 
| 30 | 
            -
                    root
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                def serializer_for(item)
         | 
| 35 | 
            -
                  serializer_class = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer
         | 
| 36 | 
            -
                  serializer_class.new(item, scope: scope)
         | 
| 37 | 
            -
                end
         | 
| 38 | 
            -
             | 
| 39 | 
            -
                def serializable_object
         | 
| 27 | 
            +
                def serializable_array
         | 
| 40 28 | 
             
                  @object.map do |item|
         | 
| 41 | 
            -
                    serializer_for(item) | 
| 42 | 
            -
             | 
| 43 | 
            -
                end
         | 
| 44 | 
            -
                alias_method :serializable_array, :serializable_object
         | 
| 45 | 
            -
             | 
| 46 | 
            -
                def embedded_in_root_associations
         | 
| 47 | 
            -
                  @object.each_with_object({}) do |item, hash|
         | 
| 48 | 
            -
                    serializer_for(item).embedded_in_root_associations.each_pair do |type, objects|
         | 
| 49 | 
            -
                      next if !objects || objects.flatten.empty?
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                      if hash.has_key?(type)
         | 
| 52 | 
            -
                        hash[type].concat(objects).uniq!
         | 
| 53 | 
            -
                      else
         | 
| 54 | 
            -
                        hash[type] = objects
         | 
| 55 | 
            -
                      end
         | 
| 56 | 
            -
                    end
         | 
| 29 | 
            +
                    serializer = @each_serializer || Serializer.serializer_for(item) || DefaultSerializer
         | 
| 30 | 
            +
                    serializer.new(item, @options).serializable_object
         | 
| 57 31 | 
             
                  end
         | 
| 58 32 | 
             
                end
         | 
| 33 | 
            +
                alias_method :serializable_object, :serializable_array
         | 
| 59 34 | 
             
              end
         | 
| 60 35 | 
             
            end
         | 
| @@ -1,27 +1,18 @@ | |
| 1 | 
            -
            require 'active_model/serializable'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module ActiveModel
         | 
| 4 2 | 
             
              # DefaultSerializer
         | 
| 5 3 | 
             
              #
         | 
| 6 4 | 
             
              # Provides a constant interface for all items
         | 
| 7 5 | 
             
              class DefaultSerializer
         | 
| 8 | 
            -
                include ActiveModel::Serializable
         | 
| 9 | 
            -
             | 
| 10 6 | 
             
                attr_reader :object
         | 
| 11 7 |  | 
| 12 8 | 
             
                def initialize(object, options=nil)
         | 
| 13 9 | 
             
                  @object = object
         | 
| 14 10 | 
             
                end
         | 
| 15 11 |  | 
| 16 | 
            -
                def  | 
| 12 | 
            +
                def serializable_hash(*)
         | 
| 17 13 | 
             
                  return nil if @object.nil?
         | 
| 18 | 
            -
                   | 
| 19 | 
            -
                    Hash[@object.members.zip(@object.values)]
         | 
| 20 | 
            -
                  else
         | 
| 21 | 
            -
                    @object.as_json
         | 
| 22 | 
            -
                  end
         | 
| 14 | 
            +
                  @object.as_json
         | 
| 23 15 | 
             
                end
         | 
| 24 | 
            -
                alias serializable_hash | 
| 25 | 
            -
                alias serializable_object as_json
         | 
| 16 | 
            +
                alias serializable_object serializable_hash
         | 
| 26 17 | 
             
              end
         | 
| 27 18 | 
             
            end
         | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            module ActiveModel
         | 
| 2 2 | 
             
              module Serializable
         | 
| 3 3 | 
             
                def as_json(options={})
         | 
| 4 | 
            -
                  if root = options | 
| 4 | 
            +
                  if root = options[:root] || self.root
         | 
| 5 5 | 
             
                    hash = { root => serializable_object }
         | 
| 6 6 | 
             
                    hash.merge!(serializable_data)
         | 
| 7 7 | 
             
                    hash
         | 
| @@ -11,15 +11,11 @@ module ActiveModel | |
| 11 11 | 
             
                end
         | 
| 12 12 |  | 
| 13 13 | 
             
                def serializable_data
         | 
| 14 | 
            -
                   | 
| 15 | 
            -
                     | 
| 16 | 
            -
             | 
| 17 | 
            -
                     | 
| 14 | 
            +
                  if respond_to?(:meta) && meta
         | 
| 15 | 
            +
                    { meta_key => meta }
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    {}
         | 
| 18 18 | 
             
                  end
         | 
| 19 19 | 
             
                end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                def embedded_in_root_associations
         | 
| 22 | 
            -
                  {}
         | 
| 23 | 
            -
                end
         | 
| 24 20 | 
             
              end
         | 
| 25 21 | 
             
            end
         | 
| @@ -13,84 +13,46 @@ module ActiveModel | |
| 13 13 |  | 
| 14 14 | 
             
                    @name          = name.to_s
         | 
| 15 15 | 
             
                    @options       = options
         | 
| 16 | 
            -
                    self.embed     = options.fetch(:embed) | 
| 16 | 
            +
                    self.embed     = options.fetch(:embed)   { CONFIG.embed }
         | 
| 17 17 | 
             
                    @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } }
         | 
| 18 18 | 
             
                    @embed_key     = options[:embed_key] || :id
         | 
| 19 19 | 
             
                    @key           = options[:key]
         | 
| 20 20 | 
             
                    @embedded_key  = options[:root] || name
         | 
| 21 21 |  | 
| 22 | 
            -
                     | 
| 23 | 
            -
                    @serializer_from_options = serializer.is_a?(String) ? serializer.constantize : serializer
         | 
| 22 | 
            +
                    self.serializer_class = @options[:serializer]
         | 
| 24 23 | 
             
                  end
         | 
| 25 24 |  | 
| 26 | 
            -
                  attr_reader :name, :embed_ids, :embed_objects
         | 
| 27 | 
            -
                  attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, : | 
| 25 | 
            +
                  attr_reader :name, :embed_ids, :embed_objects, :serializer_class
         | 
| 26 | 
            +
                  attr_accessor :embed_in_root, :embed_key, :key, :embedded_key, :options
         | 
| 28 27 | 
             
                  alias embed_ids? embed_ids
         | 
| 29 28 | 
             
                  alias embed_objects? embed_objects
         | 
| 30 29 | 
             
                  alias embed_in_root? embed_in_root
         | 
| 31 30 |  | 
| 31 | 
            +
                  def serializer_class=(serializer)
         | 
| 32 | 
            +
                    @serializer_class = serializer.is_a?(String) ? serializer.constantize : serializer
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
             | 
| 32 35 | 
             
                  def embed=(embed)
         | 
| 33 36 | 
             
                    @embed_ids     = embed == :id || embed == :ids
         | 
| 34 37 | 
             
                    @embed_objects = embed == :object || embed == :objects
         | 
| 35 38 | 
             
                  end
         | 
| 36 39 |  | 
| 37 | 
            -
                  def  | 
| 38 | 
            -
                    Serializer.serializer_for(object)
         | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
                  def default_serializer
         | 
| 42 | 
            -
                    DefaultSerializer
         | 
| 43 | 
            -
                  end
         | 
| 44 | 
            -
             | 
| 45 | 
            -
                  def build_serializer(object, options = {})
         | 
| 46 | 
            -
                    serializer_class(object).new(object, options.merge(self.options))
         | 
| 40 | 
            +
                  def build_serializer(object)
         | 
| 41 | 
            +
                    @serializer_class ||= Serializer.serializer_for(object) || DefaultSerializer
         | 
| 42 | 
            +
                    @serializer_class.new(object, @options)
         | 
| 47 43 | 
             
                  end
         | 
| 48 44 |  | 
| 49 45 | 
             
                  class HasOne < Association
         | 
| 50 | 
            -
                    def initialize( | 
| 51 | 
            -
                      super
         | 
| 52 | 
            -
                      @root_key = @embedded_key.to_s.pluralize
         | 
| 53 | 
            -
                      @key ||= "#{name}_id"
         | 
| 54 | 
            -
                    end
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                    def serializer_class(object)
         | 
| 57 | 
            -
                      serializer_from_options || serializer_from_object(object) || default_serializer
         | 
| 58 | 
            -
                    end
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                    def build_serializer(object, options = {})
         | 
| 61 | 
            -
                      options[:_wrap_in_array] = embed_in_root?
         | 
| 46 | 
            +
                    def initialize(*args)
         | 
| 62 47 | 
             
                      super
         | 
| 48 | 
            +
                      @key  ||= "#{name}_id"
         | 
| 63 49 | 
             
                    end
         | 
| 64 50 | 
             
                  end
         | 
| 65 51 |  | 
| 66 52 | 
             
                  class HasMany < Association
         | 
| 67 | 
            -
                    def initialize( | 
| 53 | 
            +
                    def initialize(*args)
         | 
| 68 54 | 
             
                      super
         | 
| 69 | 
            -
                      @ | 
| 70 | 
            -
                      @key ||= "#{name.to_s.singularize}_ids"
         | 
| 71 | 
            -
                    end
         | 
| 72 | 
            -
             | 
| 73 | 
            -
                    def serializer_class(object)
         | 
| 74 | 
            -
                      if use_array_serializer?
         | 
| 75 | 
            -
                        ArraySerializer
         | 
| 76 | 
            -
                      else
         | 
| 77 | 
            -
                        serializer_from_options
         | 
| 78 | 
            -
                      end
         | 
| 79 | 
            -
                    end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                    def options
         | 
| 82 | 
            -
                      if use_array_serializer?
         | 
| 83 | 
            -
                        { each_serializer: serializer_from_options }.merge! super
         | 
| 84 | 
            -
                      else
         | 
| 85 | 
            -
                        super
         | 
| 86 | 
            -
                      end
         | 
| 87 | 
            -
                    end
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                    private
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                    def use_array_serializer?
         | 
| 92 | 
            -
                      !serializer_from_options ||
         | 
| 93 | 
            -
                        serializer_from_options && !(serializer_from_options <= ArraySerializer)
         | 
| 55 | 
            +
                      @key ||= "#{name.singularize}_ids"
         | 
| 94 56 | 
             
                    end
         | 
| 95 57 | 
             
                  end
         | 
| 96 58 | 
             
                end
         | 
| @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            module ActiveModel
         | 
| 2 2 | 
             
              class Railtie < Rails::Railtie
         | 
| 3 3 | 
             
                initializer 'generators' do |app|
         | 
| 4 | 
            -
                   | 
| 4 | 
            +
                  require 'rails/generators'
         | 
| 5 5 | 
             
                  require 'active_model/serializer/generators/serializer/serializer_generator'
         | 
| 6 | 
            -
                   | 
| 6 | 
            +
                  Rails::Generators.configure!(app.config.generators)
         | 
| 7 7 | 
             
                  require 'active_model/serializer/generators/resource_override'
         | 
| 8 8 | 
             
                end
         | 
| 9 9 | 
             
              end
         | 
| @@ -15,33 +15,13 @@ end | |
| 15 15 | 
             
            module ActiveModel
         | 
| 16 16 | 
             
              class Serializer
         | 
| 17 17 | 
             
                include Serializable
         | 
| 18 | 
            -
                extend ActiveSupport::Inflector
         | 
| 19 18 |  | 
| 20 19 | 
             
                @mutex = Mutex.new
         | 
| 21 20 |  | 
| 22 21 | 
             
                class << self
         | 
| 23 22 | 
             
                  def inherited(base)
         | 
| 24 | 
            -
                    base. | 
| 25 | 
            -
                    base. | 
| 26 | 
            -
                    base._associations = (_associations || {}).dup
         | 
| 27 | 
            -
                  end
         | 
| 28 | 
            -
                  def const_regexp(camel_cased_word) #:nodoc:
         | 
| 29 | 
            -
                    parts = camel_cased_word.split("::")
         | 
| 30 | 
            -
                    last  = parts.pop
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                    parts.reverse.inject(last) do |acc, part|
         | 
| 33 | 
            -
                      part.empty? ? acc : "#{part}(::#{acc})?"
         | 
| 34 | 
            -
                    end
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
                  def safe_constantize(camel_cased_word)
         | 
| 37 | 
            -
                    begin
         | 
| 38 | 
            -
                      constantize(camel_cased_word)
         | 
| 39 | 
            -
                    rescue NameError => e
         | 
| 40 | 
            -
                      raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
         | 
| 41 | 
            -
                        e.name.to_s == camel_cased_word.to_s
         | 
| 42 | 
            -
                    rescue ArgumentError => e
         | 
| 43 | 
            -
                      raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
         | 
| 44 | 
            -
                    end
         | 
| 23 | 
            +
                    base._attributes = []
         | 
| 24 | 
            +
                    base._associations = {}
         | 
| 45 25 | 
             
                  end
         | 
| 46 26 |  | 
| 47 27 | 
             
                  def setup
         | 
| @@ -81,7 +61,7 @@ end | |
| 81 61 | 
             
                      if resource.respond_to?(:to_ary)
         | 
| 82 62 | 
             
                        ArraySerializer
         | 
| 83 63 | 
             
                      else
         | 
| 84 | 
            -
                         | 
| 64 | 
            +
                        "#{resource.class.name}Serializer".safe_constantize
         | 
| 85 65 | 
             
                      end
         | 
| 86 66 | 
             
                    end
         | 
| 87 67 | 
             
                  end
         | 
| @@ -128,21 +108,19 @@ end | |
| 128 108 | 
             
                end
         | 
| 129 109 |  | 
| 130 110 | 
             
                def initialize(object, options={})
         | 
| 131 | 
            -
                  @object | 
| 132 | 
            -
                  @scope | 
| 133 | 
            -
                   | 
| 134 | 
            -
                  @meta_key | 
| 135 | 
            -
                  @meta | 
| 136 | 
            -
                  @wrap_in_array = options[:_wrap_in_array]
         | 
| 111 | 
            +
                  @object   = object
         | 
| 112 | 
            +
                  @scope    = options[:scope]
         | 
| 113 | 
            +
                  self.root = options[:root]
         | 
| 114 | 
            +
                  @meta_key = options[:meta_key] || :meta
         | 
| 115 | 
            +
                  @meta     = options[@meta_key]
         | 
| 137 116 | 
             
                end
         | 
| 138 | 
            -
                attr_accessor :object, :scope, : | 
| 117 | 
            +
                attr_accessor :object, :scope, :meta_key, :meta
         | 
| 118 | 
            +
                attr_reader :root
         | 
| 139 119 |  | 
| 140 | 
            -
                def  | 
| 141 | 
            -
                   | 
| 142 | 
            -
             | 
| 143 | 
            -
                   | 
| 144 | 
            -
                    root
         | 
| 145 | 
            -
                  end
         | 
| 120 | 
            +
                def root=(root)
         | 
| 121 | 
            +
                  @root = root
         | 
| 122 | 
            +
                  @root = self.class._root if @root.nil?
         | 
| 123 | 
            +
                  @root = self.class.root_name if @root == true || @root.nil?
         | 
| 146 124 | 
             
                end
         | 
| 147 125 |  | 
| 148 126 | 
             
                def attributes
         | 
| @@ -169,34 +147,31 @@ end | |
| 169 147 | 
             
                  keys
         | 
| 170 148 | 
             
                end
         | 
| 171 149 |  | 
| 150 | 
            +
                def serializable_data
         | 
| 151 | 
            +
                  embedded_in_root_associations.merge!(super)
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 172 154 | 
             
                def embedded_in_root_associations
         | 
| 173 155 | 
             
                  associations = self.class._associations
         | 
| 174 156 | 
             
                  included_associations = filter(associations.keys)
         | 
| 175 157 | 
             
                  associations.each_with_object({}) do |(name, association), hash|
         | 
| 176 158 | 
             
                    if included_associations.include? name
         | 
| 177 159 | 
             
                      if association.embed_in_root?
         | 
| 178 | 
            -
                         | 
| 179 | 
            -
                        hash.merge! association_serializer.embedded_in_root_associations
         | 
| 180 | 
            -
             | 
| 181 | 
            -
                        serialized_data = association_serializer.serializable_object
         | 
| 182 | 
            -
                        key = association.root_key
         | 
| 183 | 
            -
                        if hash.has_key?(key)
         | 
| 184 | 
            -
                          hash[key].concat(serialized_data).uniq!
         | 
| 185 | 
            -
                        else
         | 
| 186 | 
            -
                          hash[key] = serialized_data
         | 
| 187 | 
            -
                        end
         | 
| 160 | 
            +
                        hash[association.embedded_key] = serialize association
         | 
| 188 161 | 
             
                      end
         | 
| 189 162 | 
             
                    end
         | 
| 190 163 | 
             
                  end
         | 
| 191 164 | 
             
                end
         | 
| 192 165 |  | 
| 193 | 
            -
                def build_serializer(association)
         | 
| 194 | 
            -
                  object = send(association.name)
         | 
| 195 | 
            -
                  association.build_serializer(object, scope: scope)
         | 
| 196 | 
            -
                end
         | 
| 197 | 
            -
             | 
| 198 166 | 
             
                def serialize(association)
         | 
| 199 | 
            -
                   | 
| 167 | 
            +
                  associated_data = send(association.name)
         | 
| 168 | 
            +
                  if associated_data.respond_to?(:to_ary) &&
         | 
| 169 | 
            +
                     !(association.serializer_class &&
         | 
| 170 | 
            +
                       association.serializer_class <= ArraySerializer)
         | 
| 171 | 
            +
                    associated_data.map { |elem| association.build_serializer(elem).serializable_hash }
         | 
| 172 | 
            +
                  else
         | 
| 173 | 
            +
                    association.build_serializer(associated_data).serializable_object
         | 
| 174 | 
            +
                  end
         | 
| 200 175 | 
             
                end
         | 
| 201 176 |  | 
| 202 177 | 
             
                def serialize_ids(association)
         | 
| @@ -208,13 +183,11 @@ end | |
| 208 183 | 
             
                  end
         | 
| 209 184 | 
             
                end
         | 
| 210 185 |  | 
| 211 | 
            -
                def  | 
| 186 | 
            +
                def serializable_hash(options={})
         | 
| 212 187 | 
             
                  return nil if object.nil?
         | 
| 213 188 | 
             
                  hash = attributes
         | 
| 214 189 | 
             
                  hash.merge! associations
         | 
| 215 | 
            -
                  @wrap_in_array ? [hash] : hash
         | 
| 216 190 | 
             
                end
         | 
| 217 | 
            -
                alias_method : | 
| 191 | 
            +
                alias_method :serializable_object, :serializable_hash
         | 
| 218 192 | 
             
              end
         | 
| 219 | 
            -
             | 
| 220 193 | 
             
            end
         | 
| @@ -1,26 +1,10 @@ | |
| 1 1 | 
             
            require 'active_support'
         | 
| 2 | 
            -
            require ' | 
| 2 | 
            +
            require 'active_model/as_json_overrides'
         | 
| 3 3 | 
             
            require 'active_model/serializer'
         | 
| 4 4 | 
             
            require 'active_model/serializer_support'
         | 
| 5 5 | 
             
            require 'active_model/serializer/version'
         | 
| 6 | 
            -
            require 'active_model/serializer/railtie' if defined?(Rails) | 
| 6 | 
            +
            require 'active_model/serializer/railtie' if defined?(Rails)
         | 
| 7 7 |  | 
| 8 | 
            -
            ActiveModel::Errors = ActiveRecord::Errors #fix for authlogic gem
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            module ActiveSupport
         | 
| 11 | 
            -
              module Inflector
         | 
| 12 | 
            -
                def safe_constantize(camel_cased_word)
         | 
| 13 | 
            -
                  begin
         | 
| 14 | 
            -
                    constantize(camel_cased_word)
         | 
| 15 | 
            -
                  rescue NameError => e
         | 
| 16 | 
            -
                    raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
         | 
| 17 | 
            -
                      e.name.to_s == camel_cased_word.to_s
         | 
| 18 | 
            -
                  rescue ArgumentError => e
         | 
| 19 | 
            -
                    raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
         | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
                end
         | 
| 22 | 
            -
              end
         | 
| 23 | 
            -
            end
         | 
| 24 8 | 
             
            begin
         | 
| 25 9 | 
             
              require 'action_controller'
         | 
| 26 10 | 
             
              require 'action_controller/serialization'
         | 
    
        data/test/coverage_setup.rb
    CHANGED
    
    | @@ -1,15 +1,12 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
             | 
| 3 | 
            -
              require 'coveralls'
         | 
| 1 | 
            +
            require 'simplecov'
         | 
| 2 | 
            +
            require 'coveralls'
         | 
| 4 3 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 4 | 
            +
            SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
         | 
| 5 | 
            +
              SimpleCov::Formatter::HTMLFormatter,
         | 
| 6 | 
            +
              Coveralls::SimpleCov::Formatter
         | 
| 7 | 
            +
            ]
         | 
| 9 8 |  | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
              end
         | 
| 14 | 
            -
            rescue LoadError
         | 
| 9 | 
            +
            SimpleCov.start do
         | 
| 10 | 
            +
              add_group "lib", "lib"
         | 
| 11 | 
            +
              add_group "test", "test"
         | 
| 15 12 | 
             
            end
         | 
| @@ -80,13 +80,13 @@ ARPost.create(title: 'New post', | |
| 80 80 |  | 
| 81 81 | 
             
              short_tag = post.ar_tags.create(name: 'short')
         | 
| 82 82 | 
             
              whiny_tag = post.ar_tags.create(name: 'whiny')
         | 
| 83 | 
            -
              happy_tag =  | 
| 83 | 
            +
              happy_tag = post.ar_tags.create(name: 'happy')
         | 
| 84 84 |  | 
| 85 85 | 
             
              post.ar_comments.create(body: 'what a dumb post').tap do |comment|
         | 
| 86 | 
            -
                comment.ar_tags.concat  | 
| 86 | 
            +
                comment.ar_tags.concat short_tag, whiny_tag
         | 
| 87 87 | 
             
              end
         | 
| 88 88 |  | 
| 89 89 | 
             
              post.ar_comments.create(body: 'i liked it').tap do |comment|
         | 
| 90 | 
            -
                comment.ar_tags.concat  | 
| 90 | 
            +
                comment.ar_tags.concat short_tag, happy_tag
         | 
| 91 91 | 
             
              end
         | 
| 92 92 | 
             
            end
         | 
| @@ -3,7 +3,7 @@ require 'fixtures/active_record' | |
| 3 3 |  | 
| 4 4 | 
             
            module ActiveModel
         | 
| 5 5 | 
             
              class Serializer
         | 
| 6 | 
            -
                class ActiveRecordTest <  | 
| 6 | 
            +
                class ActiveRecordTest < ActiveRecord::TestCase
         | 
| 7 7 | 
             
                  def setup
         | 
| 8 8 | 
             
                    @post = ARPost.first
         | 
| 9 9 | 
             
                  end
         | 
| @@ -14,9 +14,9 @@ module ActiveModel | |
| 14 14 | 
             
                    assert_equal({
         | 
| 15 15 | 
             
                      'ar_post' => {
         | 
| 16 16 | 
             
                        title: 'New post', body: 'A body!!!',
         | 
| 17 | 
            -
                        ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: ' | 
| 18 | 
            -
                                      { body: 'i liked it', ar_tags: [{:name=>" | 
| 19 | 
            -
                        ar_tags: [{ name: 'short' }, { name: 'whiny' }],
         | 
| 17 | 
            +
                        ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: 'short' }, { name: 'whiny' }] },
         | 
| 18 | 
            +
                                      { body: 'i liked it', ar_tags: [{:name=>"short"}, {:name=>"happy"}] }],
         | 
| 19 | 
            +
                        ar_tags: [{ name: 'short' }, { name: 'whiny' }, { name: 'happy' }],
         | 
| 20 20 | 
             
                        ar_section: { 'name' => 'ruby' }
         | 
| 21 21 | 
             
                      }
         | 
| 22 22 | 
             
                    }, post_serializer.as_json)
         | 
| @@ -30,7 +30,7 @@ module ActiveModel | |
| 30 30 | 
             
                        'ar_post' => {
         | 
| 31 31 | 
             
                          title: 'New post', body: 'A body!!!',
         | 
| 32 32 | 
             
                          'ar_comment_ids' => [1, 2],
         | 
| 33 | 
            -
                          'ar_tag_ids' => [1, 2],
         | 
| 33 | 
            +
                          'ar_tag_ids' => [1, 2, 3],
         | 
| 34 34 | 
             
                          'ar_section_id' => 1
         | 
| 35 35 | 
             
                        }
         | 
| 36 36 | 
             
                      }, post_serializer.as_json)
         | 
| @@ -41,36 +41,34 @@ module ActiveModel | |
| 41 41 | 
             
                    post_serializer = ARPostSerializer.new(@post)
         | 
| 42 42 |  | 
| 43 43 | 
             
                    embed(ARPostSerializer, embed: :ids, embed_in_root: true) do
         | 
| 44 | 
            -
                       | 
| 45 | 
            -
                         | 
| 46 | 
            -
                          ' | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 49 | 
            -
             | 
| 50 | 
            -
             | 
| 51 | 
            -
             | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
                        }, post_serializer.as_json)
         | 
| 57 | 
            -
                      end
         | 
| 44 | 
            +
                      assert_equal({
         | 
| 45 | 
            +
                        'ar_post' => {
         | 
| 46 | 
            +
                          title: 'New post', body: 'A body!!!',
         | 
| 47 | 
            +
                          'ar_comment_ids' => [1, 2],
         | 
| 48 | 
            +
                          'ar_tag_ids' => [1, 2, 3],
         | 
| 49 | 
            +
                          'ar_section_id' => 1
         | 
| 50 | 
            +
                        },
         | 
| 51 | 
            +
                        ar_comments: [{ body: 'what a dumb post', ar_tags: [{ name: 'short' }, { name: 'whiny' }] },
         | 
| 52 | 
            +
                                      { body: 'i liked it', ar_tags: [{:name=>"short"}, {:name=>"happy"}] }],
         | 
| 53 | 
            +
                        ar_tags: [{ name: 'short' }, { name: 'whiny' }, { name: 'happy' }],
         | 
| 54 | 
            +
                        ar_section: { 'name' => 'ruby' }
         | 
| 55 | 
            +
                      }, post_serializer.as_json)
         | 
| 58 56 | 
             
                    end
         | 
| 59 57 | 
             
                  end
         | 
| 60 58 |  | 
| 61 59 | 
             
                  private
         | 
| 62 60 |  | 
| 63 | 
            -
                  def embed( | 
| 64 | 
            -
                    old_assocs = Hash[ | 
| 61 | 
            +
                  def embed(klass, options = {})
         | 
| 62 | 
            +
                    old_assocs = Hash[ARPostSerializer._associations.to_a.map { |(name, association)| [name, association.dup] }]
         | 
| 65 63 |  | 
| 66 | 
            -
                     | 
| 64 | 
            +
                    ARPostSerializer._associations.each_value do |association|
         | 
| 67 65 | 
             
                      association.embed = options[:embed]
         | 
| 68 66 | 
             
                      association.embed_in_root = options[:embed_in_root]
         | 
| 69 67 | 
             
                    end
         | 
| 70 68 |  | 
| 71 69 | 
             
                    yield
         | 
| 72 70 | 
             
                  ensure
         | 
| 73 | 
            -
                     | 
| 71 | 
            +
                    ARPostSerializer._associations = old_assocs
         | 
| 74 72 | 
             
                  end
         | 
| 75 73 | 
             
                end
         | 
| 76 74 | 
             
              end
         |