diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a001825b..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: ruby -rvm: - - 1.9.3 - - 2.0.0 - - jruby-19mode - - rbx-19mode -gemfile: - - Gemfile - - Gemfile.edge -matrix: - allow_failures: - - gemfile: Gemfile.edge -notifications: - email: false - campfire: - on_success: change - rooms: - - secure: "TP0fJ4aqXCRD7CaAgaYW7Pa22j4/uLChdBb59ob/sJvHtfi4Zx3I54xWApmp\nZl1KItFGCV8oQZhQl5hAmHJfJ+1gCNeBvIKwY6TsIyTmyDg1KcJUcJDrwYxO\ntAeYI2PvU5PtKMmpnfnwFQMxL+2nfWJWNzboBCDr4YvoFI+rN+A=" diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index b4c2913d..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,113 +0,0 @@ -# UNRELEASED - -* ActiveModel::Serializable was created it has the shared code between - AM::Serializer and AM::ArraySerializer. Basically enable objects to be - serializable by implementing an options method to handle the options - of the serialization and a serialize method that returns an object to - be converted to json by the module. This also removes duplicate code. - https://github.com/rails-api/active_model_serializers/commit/6c6bc8872d3b0f040a200854fa5530a775824dbf - -* ActiveModel::Serializer::Caching module was created it enables - Serializers to be able to cache to\_json and serialize calls. This - also helps removing duplicate code. - https://github.com/rails-api/active_model_serializers/commit/3e27110df78696ac48cafd1568f72216f348a188 - -* We got rid of the Association.refine method which generated - subclasses. - https://github.com/rails-api/active_model_serializers/commit/24923722d4f215c7cfcdf553fd16582e28e3801b - -* Associations doesn't know anymore about the source serializer. - That didn't make any sense. - https://github.com/rails-api/active_model_serializers/commit/2252e8fe6dbf45660c6a35f35e2423792f2c3abf - https://github.com/rails-api/active_model_serializers/commit/87eadd09b9a988bc1d9b30d9a501ef7e3fc6bb87 - https://github.com/rails-api/active_model_serializers/commit/79a6e13e8f7fae2eb4f48e83a9633e74beb6739e - -* Passing options[:hash] is not public API of include!. That was - removed. - https://github.com/rails-api/active_model_serializers/commit/5cbf9317051002a32c90c3f995b8b2f126f70d0c - -* ActiveModel::Serializer::Associations::Config is now - ActiveModel::Serializer::Association but it's an internal - thing so shouldn't bother. - ActiveModel::Serializer::Associations::Has\* are now - ActiveModel::Serializer::Association::Has\* and inherit from - ActiveModel::Serializer::Association - https://github.com/rails-api/active_model_serializers/commit/f5de334ddf1f3b9764d914a717311532021785d2 - https://github.com/rails-api/active_model_serializers/commit/3dd422d99e8c57f113880da34f6abe583c4dadf9 - -* serialize\_ids call methods on the corresponding serializer if they - are defined, instead of talking directly with the serialized object. - Serializers are decorators so we shouldn't talk directly with - serialized objects. - -* Array items are not wrapped anymore in root element. - -* Remove support for ruby 1.8 versions. - -* Require rails >= 3.2. - -# VERSION 0.8.1 - -* Fix bug whereby a serializer using 'options' would blow up. - -# VERSION 0.8.0 - -* Attributes can now have optional types. - -* A new DefaultSerializer ensures that POROs behave the same way as ActiveModels. - -* If you wish to override ActiveRecord::Base#to\_Json, you can now require - 'active\_record/serializer\_override'. We don't recommend you do this, but - many users do, so we've left it optional. - -* Fixed a bug where ActionController wouldn't always have MimeResponds. - -* An optinal caching feature allows you to cache JSON & hashes that AMS uses. - Adding 'cached true' to your Serializers will turn on this cache. - -* URL helpers used inside of Engines now work properly. - -* Serializers now can filter attributes with `only` and `except`: - - ``` - UserSerializer.new(user, only: [:first_name, :last_name]) - UserSerializer.new(user, except: :first_name) - ``` - -* Basic Mongoid support. We now include our mixins in the right place. - -* On Ruby 1.8, we now generate an `id` method that properly serializes `id` - columns. See issue #127 for more. - -* Add an alias for `scope` method to be the name of the context. By default - this is `current_user`. The name is automatically set when using - `serialization_scope` in the controller. - -* Pass through serialization options (such as `:include`) when a model - has no serializer defined. - -# VERSION 0.7.0 - -* ```embed_key``` option to allow embedding by attributes other than IDs -* Fix rendering nil with custom serializer -* Fix global ```self.root = false``` -* Add support for specifying the serializer for an association as a String -* Able to specify keys on the attributes method -* Serializer Reloading via ActiveSupport::DescendantsTracker -* Reduce double map to once; Fixes datamapper eager loading. - -# VERSION 0.6.0 - -* Serialize sets properly -* Add root option to ArraySerializer -* Support polymorphic associations -* Support :each_serializer in ArraySerializer -* Add `scope` method to easily access the scope in the serializer -* Fix regression with Rails 3.2.6; add Rails 4 support -* Allow serialization_scope to be disabled with serialization_scope nil -* Array serializer should support pure ruby objects besides serializers - -# VERSION 0.5.0 (May 16, 2012) - -* First tagged version -* Changes generators to always generate an ApplicationSerializer diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 9811ef28..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,20 +0,0 @@ -Contributing to AMS -=================== - -First of all, **thank you**! - -Now, for the details: - -Please file issues on the [GitHub Issues -list](https://github.com/rails-api/active_model_serializers/issues). - -Please discuss new features or ask for feedback about a new feature [on -rails-api-core](https://groups.google.com/forum/#!forum/rails-api-core). - -If you want a feature implemented, the best way to get it done is to submit a -pull request that implements it. Tests and docs would be nice. - -Please include a CHANGELOG with all entries that change behavior. - -:heart: :sparkling_heart: :heart: - diff --git a/DESIGN.textile b/DESIGN.textile deleted file mode 100644 index 559982e4..00000000 --- a/DESIGN.textile +++ /dev/null @@ -1,586 +0,0 @@ -This was the original design document for serializers. It is useful mostly for historical purposes as the public API has changed. - -h2. Rails Serializers - -This guide describes how to use Active Model serializers to build non-trivial JSON services in Rails. By reading this guide, you will learn: - -* When to use the built-in Active Model serialization -* When to use a custom serializer for your models -* How to use serializers to encapsulate authorization concerns -* How to create serializer templates to describe the application-wide structure of your serialized JSON -* How to build resources not backed by a single database table for use with JSON services - -This guide covers an intermediate topic and assumes familiarity with Rails conventions. It is suitable for applications that expose a -JSON API that may return different results based on the authorization status of the user. - -h3. Serialization - -By default, Active Record objects can serialize themselves into JSON by using the `to_json` method. This method takes a series of additional -parameter to control which properties and associations Rails should include in the serialized output. - -When building a web application that uses JavaScript to retrieve JSON data from the server, this mechanism has historically been the primary -way that Rails developers prepared their responses. This works great for simple cases, as the logic for serializing an Active Record object -is neatly encapsulated in Active Record itself. - -However, this solution quickly falls apart in the face of serialization requirements based on authorization. For instance, a web service -may choose to expose additional information about a resource only if the user is entitled to access it. In addition, a JavaScript front-end -may want information that is not neatly described in terms of serializing a single Active Record object, or in a different format than. - -In addition, neither the controller nor the model seems like the correct place for logic that describes how to serialize an model object -*for the current user*. - -Serializers solve these problems by encapsulating serialization in an object designed for this purpose. If the default +to_json+ semantics, -with at most a few configuration options serve your needs, by all means continue to use the built-in +to_json+. If you find yourself doing -hash-driven-development in your controllers, juggling authorization logic and other concerns, serializers are for you! - -h3. The Most Basic Serializer - -A basic serializer is a simple Ruby object named after the model class it is serializing. - -
-class PostSerializer
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- def as_json
- { post: { title: @post.name, body: @post.body } }
- end
-end
-
-
-A serializer is initialized with two parameters: the model object it should serialize and an authorization scope. By default, the
-authorization scope is the current user (+current_user+) but you can use a different object if you want. The serializer also
-implements an +as_json+ method, which returns a Hash that will be sent to the JSON encoder.
-
-Rails will transparently use your serializer when you use +render :json+ in your controller.
-
-
-class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
- render json: @post
- end
-end
-
-
-Because +respond_with+ uses +render :json+ under the hood for JSON requests, Rails will automatically use your serializer when
-you use +respond_with+ as well.
-
-h4. +serializable_hash+
-
-In general, you will want to implement +serializable_hash+ and +as_json+ to allow serializers to embed associated content
-directly. The easiest way to implement these two methods is to have +as_json+ call +serializable_hash+ and insert the root.
-
-
-class PostSerializer
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- def serializable_hash
- { title: @post.name, body: @post.body }
- end
-
- def as_json
- { post: serializable_hash }
- end
-end
-
-
-h4. Authorization
-
-Let's update our serializer to include the email address of the author of the post, but only if the current user has superuser
-access.
-
-
-class PostSerializer
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- def as_json
- { post: serializable_hash }
- end
-
- def serializable_hash
- hash = post
- hash.merge!(super_data) if super?
- hash
- end
-
-private
- def post
- { title: @post.name, body: @post.body }
- end
-
- def super_data
- { email: @post.email }
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-h4. Testing
-
-One benefit of encapsulating our objects this way is that it becomes extremely straight-forward to test the serialization
-logic in isolation.
-
-
-require "ostruct"
-
-class PostSerializerTest < ActiveSupport::TestCase
- # For now, we use a very simple authorization structure. These tests will need
- # refactoring if we change that.
- plebe = OpenStruct.new(super?: false)
- god = OpenStruct.new(super?: true)
-
- post = OpenStruct.new(title: "Welcome to my blog!", body: "Blah blah blah", email: "tenderlove@gmail.com")
-
- test "a regular user sees just the title and body" do
- json = PostSerializer.new(post, plebe).to_json
- hash = JSON.parse(json)
-
- assert_equal post.title, hash.delete("title")
- assert_equal post.body, hash.delete("body")
- assert_empty hash
- end
-
- test "a superuser sees the title, body and email" do
- json = PostSerializer.new(post, god).to_json
- hash = JSON.parse(json)
-
- assert_equal post.title, hash.delete("title")
- assert_equal post.body, hash.delete("body")
- assert_equal post.email, hash.delete("email")
- assert_empty hash
- end
-end
-
-
-It's important to note that serializer objects define a clear interface specifically for serializing an existing object.
-In this case, the serializer expects to receive a post object with +name+, +body+ and +email+ attributes and an authorization
-scope with a +super?+ method.
-
-By defining a clear interface, it's must easier to ensure that your authorization logic is behaving correctly. In this case,
-the serializer doesn't need to concern itself with how the authorization scope decides whether to set the +super?+ flag, just
-whether it is set. In general, you should document these requirements in your serializer files and programatically via tests.
-The documentation library +YARD+ provides excellent tools for describing this kind of requirement:
-
-
-class PostSerializer
- # @param [~body, ~title, ~email] post the post to serialize
- # @param [~super] scope the authorization scope for this serializer
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- # ...
-end
-
-
-h3. Attribute Sugar
-
-To simplify this process for a number of common cases, Rails provides a default superclass named +ActiveModel::Serializer+
-that you can use to implement your serializers.
-
-For example, you will sometimes want to simply include a number of existing attributes from the source model into the outputted
-JSON. In the above example, the +title+ and +body+ attributes were always included in the JSON. Let's see how to use
-+ActiveModel::Serializer+ to simplify our post serializer.
-
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- def serializable_hash
- hash = attributes
- hash.merge!(super_data) if super?
- hash
- end
-
-private
- def super_data
- { email: @post.email }
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-First, we specified the list of included attributes at the top of the class. This will create an instance method called
-+attributes+ that extracts those attributes from the post model.
-
-NOTE: Internally, +ActiveModel::Serializer+ uses +read_attribute_for_serialization+, which defaults to +read_attribute+, which defaults to +send+. So if you're rolling your own models for use with the serializer, you can use simple Ruby accessors for your attributes if you like.
-
-Next, we use the attributes method in our +serializable_hash+ method, which allowed us to eliminate the +post+ method we hand-rolled
-earlier. We could also eliminate the +as_json+ method, as +ActiveModel::Serializer+ provides a default +as_json+ method for
-us that calls our +serializable_hash+ method and inserts a root. But we can go a step further!
-
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
-
-private
- def attributes
- hash = super
- hash.merge!(email: post.email) if super?
- hash
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-The superclass provides a default +initialize+ method as well as a default +serializable_hash+ method, which uses
-+attributes+. We can call +super+ to get the hash based on the attributes we declared, and then add in any additional
-attributes we want to use.
-
-NOTE: +ActiveModel::Serializer+ will create an accessor matching the name of the current class for the resource you pass in. In this case, because we have defined a PostSerializer, we can access the resource with the +post+ accessor.
-
-h3. Associations
-
-In most JSON APIs, you will want to include associated objects with your serialized object. In this case, let's include
-the comments with the current post.
-
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
- has_many :comments
-
-private
- def attributes
- hash = super
- hash.merge!(email: post.email) if super?
- hash
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-The default +serializable_hash+ method will include the comments as embedded objects inside the post.
-
-
-{
- post: {
- title: "Hello Blog!",
- body: "This is my first post. Isn't it fabulous!",
- comments: [
- {
- title: "Awesome",
- body: "Your first post is great"
- }
- ]
- }
-}
-
-
-Rails uses the same logic to generate embedded serializations as it does when you use +render :json+. In this case,
-because you didn't define a +CommentSerializer+, Rails used the default +as_json+ on your comment object.
-
-If you define a serializer, Rails will automatically instantiate it with the existing authorization scope.
-
-
-class CommentSerializer
- def initialize(comment, scope)
- @comment, @scope = comment, scope
- end
-
- def serializable_hash
- { title: @comment.title }
- end
-
- def as_json
- { comment: serializable_hash }
- end
-end
-
-
-If we define the above comment serializer, the outputted JSON will change to:
-
-
-{
- post: {
- title: "Hello Blog!",
- body: "This is my first post. Isn't it fabulous!",
- comments: [{ title: "Awesome" }]
- }
-}
-
-
-Let's imagine that our comment system allows an administrator to kill a comment, and we only want to allow
-users to see the comments they're entitled to see. By default, +has_many :comments+ will simply use the
-+comments+ accessor on the post object. We can override the +comments+ accessor to limit the comments used
-to just the comments we want to allow for the current user.
-
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title. :body
- has_many :comments
-
-private
- def attributes
- hash = super
- hash.merge!(email: post.email) if super?
- hash
- end
-
- def comments
- post.comments_for(scope)
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-+ActiveModel::Serializer+ will still embed the comments, but this time it will use just the comments
-for the current user.
-
-NOTE: The logic for deciding which comments a user should see still belongs in the model layer. In general, you should encapsulate concerns that require making direct Active Record queries in scopes or public methods on your models.
-
-h4. Modifying Associations
-
-You can also rename associations if required. Say for example you have an association that
-makes sense to be named one thing in your code, but another when data is serialized.
-You can use the
-class UserSerializer < ActiveModel::Serializer
- has_many :followed_posts, key: :posts
- has_one :owned_account, key: :account
-end
-
-
-Using the :key without a :serializer option will use implicit detection
-to determine a serializer. In this example, you'd have to define two classes: PostSerializer
-and AccountSerializer. You can also add the :serializer option
-to set it explicitly:
-
-
-class UserSerializer < ActiveModel::Serializer
- has_many :followed_posts, key: :posts, serializer: CustomPostSerializer
- has_one :owne_account, key: :account, serializer: PrivateAccountSerializer
-end
-
-
-h3. Customizing Associations
-
-Not all front-ends expect embedded documents in the same form. In these cases, you can override the
-default +serializable_hash+, and use conveniences provided by +ActiveModel::Serializer+ to avoid having to
-build up the hash manually.
-
-For example, let's say our front-end expects the posts and comments in the following format:
-
-
-{
- post: {
- id: 1
- title: "Hello Blog!",
- body: "This is my first post. Isn't it fabulous!",
- comments: [1,2]
- },
- comments: [
- {
- id: 1
- title: "Awesome",
- body: "Your first post is great"
- },
- {
- id: 2
- title: "Not so awesome",
- body: "Why is it so short!"
- }
- ]
-}
-
-
-We could achieve this with a custom +as_json+ method. We will also need to define a serializer for comments.
-
-
-class CommentSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- # define any logic for dealing with authorization-based attributes here
-end
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
- has_many :comments
-
- def as_json
- { post: serializable_hash }.merge!(associations)
- end
-
- def serializable_hash
- post_hash = attributes
- post_hash.merge!(association_ids)
- post_hash
- end
-
-private
- def attributes
- hash = super
- hash.merge!(email: post.email) if super?
- hash
- end
-
- def comments
- post.comments_for(scope)
- end
-
- def super?
- @scope.superuser?
- end
-end
-
-
-Here, we used two convenience methods: +associations+ and +association_ids+. The first,
-+associations+, creates a hash of all of the define associations, using their defined
-serializers. The second, +association_ids+, generates a hash whose key is the association
-name and whose value is an Array of the association's keys.
-
-The +association_ids+ helper will use the overridden version of the association, so in
-this case, +association_ids+ will only include the ids of the comments provided by the
-+comments+ method.
-
-
-h3. Special Association Serializers
-
-So far, associations defined in serializers use either the +as_json+ method on the model
-or the defined serializer for the association type. Sometimes, you may want to serialize
-associated models differently when they are requested as part of another resource than
-when they are requested on their own.
-
-For instance, we might want to provide the full comment when it is requested directly,
-but only its title when requested as part of the post. To achieve this, you can define
-a serializer for associated objects nested inside the main serializer.
-
-
-class PostSerializer < ActiveModel::Serializer
- class CommentSerializer < ActiveModel::Serializer
- attributes :id, :title
- end
-
- # same as before
- # ...
-end
-
-
-In other words, if a +PostSerializer+ is trying to serialize comments, it will first
-look for +PostSerializer::CommentSerializer+ before falling back to +CommentSerializer+
-and finally +comment.as_json+.
-
-h3. Overriding the Defaults
-
-h4. Authorization Scope
-
-By default, the authorization scope for serializers is +:current_user+. This means
-that when you call +render json: @post+, the controller will automatically call
-its +current_user+ method and pass that along to the serializer's initializer.
-
-If you want to change that behavior, simply use the +serialization_scope+ class
-method.
-
-
-class PostsController < ApplicationController
- serialization_scope :current_app
-end
-
-
-You can also implement an instance method called (no surprise) +serialization_scope+,
-which allows you to define a dynamic authorization scope based on the current request.
-
-WARNING: If you use different objects as authorization scopes, make sure that they all implement whatever interface you use in your serializers to control what the outputted JSON looks like.
-
-h3. Using Serializers Outside of a Request
-
-The serialization API encapsulates the concern of generating a JSON representation of
-a particular model for a particular user. As a result, you should be able to easily use
-serializers, whether you define them yourself or whether you use +ActiveModel::Serializer+
-outside a request.
-
-For instance, if you want to generate the JSON representation of a post for a user outside
-of a request:
-
-
-user = get_user # some logic to get the user in question
-PostSerializer.new(post, user).to_json # reliably generate JSON output
-
-
-If you want to generate JSON for an anonymous user, you should be able to use whatever
-technique you use in your application to generate anonymous users outside of a request.
-Typically, that means creating a new user and not saving it to the database:
-
-
-user = User.new # create a new anonymous user
-PostSerializer.new(post, user).to_json
-
-
-In general, the better you encapsulate your authorization logic, the more easily you
-will be able to use the serializer outside of the context of a request. For instance,
-if you use an authorization library like Cancan, which uses a uniform +user.can?(action, model)+,
-the authorization interface can very easily be replaced by a plain Ruby object for
-testing or usage outside the context of a request.
-
-h3. Collections
-
-So far, we've talked about serializing individual model objects. By default, Rails
-will serialize collections, including when using the +associations+ helper, by
-looping over each element of the collection, calling +serializable_hash+ on the element,
-and then grouping them by their type (using the plural version of their class name
-as the root).
-
-For example, an Array of post objects would serialize as:
-
-
-{
- posts: [
- {
- title: "FIRST POST!",
- body: "It's my first pooooost"
- },
- { title: "Second post!",
- body: "Zomg I made it to my second post"
- }
- ]
-}
-
-
-If you want to change the behavior of serialized Arrays, you need to create
-a custom Array serializer.
-
-
-class ArraySerializer < ActiveModel::ArraySerializer
- def serializable_array
- serializers.map do |serializer|
- serializer.serializable_hash
- end
- end
-
- def as_json
- hash = { root => serializable_array }
- hash.merge!(associations)
- hash
- end
-end
-
-
-When generating embedded associations using the +associations+ helper inside a
-regular serializer, it will create a new ArraySerializer with the
-associated content and call its +serializable_array+ method. In this case, those
-embedded associations will not recursively include associations.
-
-When generating an Array using +render json: posts+, the controller will invoke
-the +as_json+ method, which will include its associations and its root.
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index 79ab2b93..00000000
--- a/Gemfile
+++ /dev/null
@@ -1,6 +0,0 @@
-source 'https://rubygems.org'
-
-# Specify gem dependencies in active_model_serializers.gemspec
-gemspec
-
-gem "coveralls", require: false
diff --git a/Gemfile.edge b/Gemfile.edge
deleted file mode 100644
index d4e1c028..00000000
--- a/Gemfile.edge
+++ /dev/null
@@ -1,9 +0,0 @@
-source 'http://rubygems.org'
-
-gemspec
-
-gem 'rails', github: 'rails/rails'
-
-# Current dependencies of edge rails
-gem 'journey', github: 'rails/journey'
-gem 'activerecord-deprecated_finders' , github: 'rails/activerecord-deprecated_finders'
diff --git a/MIT-LICENSE.txt b/MIT-LICENSE.txt
deleted file mode 100644
index 75e6db1a..00000000
--- a/MIT-LICENSE.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Copyright (c) 2011-2012 José Valim & Yehuda Katz
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/README.md b/README.md
deleted file mode 100644
index bb7d8871..00000000
--- a/README.md
+++ /dev/null
@@ -1,716 +0,0 @@
-[](https://travis-ci.org/rails-api/active_model_serializers) [](https://codeclimate.com/github/rails-api/active_model_serializers) [](https://coveralls.io/r/rails-api/active_model_serializers)
-
-# Purpose
-
-The purpose of `ActiveModel::Serializers` is to provide an object to
-encapsulate serialization of `ActiveModel` objects, including `ActiveRecord`
-objects.
-
-Serializers know about both a model and the `current_user`, so you can
-customize serialization based upon whether a user is authorized to see the
-content.
-
-In short, **serializers replace hash-driven development with object-oriented
-development.**
-
-# Installing
-
-The easiest way to install `ActiveModel::Serializers` is to add it to your
-`Gemfile`:
-
-```ruby
-gem "active_model_serializers"
-```
-
-Then, install it on the command line:
-
-```
-$ bundle install
-```
-
-#### Ruby 1.8 is no longer supported!
-
-If you must use a ruby 1.8 version (MRI 1.8.7, REE, Rubinius 1.8, or JRuby 1.8), you need to use version 0.8.x.
-Versions after 0.9.0 do not support ruby 1.8. To specify version 0.8, include this in your Gemfile:
-
-```ruby
-gem "active_model_serializers", "~> 0.8.0"
-```
-
-
-# Creating a Serializer
-
-The easiest way to create a new serializer is to generate a new resource, which
-will generate a serializer at the same time:
-
-```
-$ rails g resource post title:string body:string
-```
-
-This will generate a serializer in `app/serializers/post_serializer.rb` for
-your new model. You can also generate a serializer for an existing model with
-the serializer generator:
-
-```
-$ rails g serializer post
-```
-
-### Support for POROs and other ORMs.
-
-Currently `ActiveModel::Serializers` adds serialization support to all models
-that descend from `ActiveRecord` or include `Mongoid::Document`. If you are
-using another ORM, or if you are using objects that are `ActiveModel`
-compliant but do not descend from `ActiveRecord` or include
-`Mongoid::Document`, you must add an include statement for
-`ActiveModel::SerializerSupport` to make models serializable. If you
-also want to make collections serializable, you should include
-`ActiveModel::ArraySerializerSupport` into your ORM's
-relation/criteria class.
-
-# ActiveModel::Serializer
-
-All new serializers descend from ActiveModel::Serializer
-
-# render :json
-
-In your controllers, when you use `render :json`, Rails will now first search
-for a serializer for the object and use it if available.
-
-```ruby
-class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
- render json: @post
- end
-end
-```
-
-In this case, Rails will look for a serializer named `PostSerializer`, and if
-it exists, use it to serialize the `Post`.
-
-This also works with `respond_with`, which uses `to_json` under the hood. Also
-note that any options passed to `render :json` will be passed to your
-serializer and available as `@options` inside.
-
-To specify a custom serializer for an object, there are 2 options:
-
-#### 1. Specify the serializer in your model:
-
-```ruby
-class Post < ActiveRecord::Base
- def active_model_serializer
- FancyPostSerializer
- end
-end
-```
-
-#### 2. Specify the serializer when you render the object:
-
-```ruby
-render json: @post, serializer: FancyPostSerializer
-```
-
-## Arrays
-
-In your controllers, when you use `render :json` for an array of objects, AMS will
-use `ActiveModel::ArraySerializer` (included in this project) as the base serializer,
-and the individual `Serializer` for the objects contained in that array.
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
-end
-
-class PostsController < ApplicationController
- def index
- @posts = Post.all
- render json: @posts
- end
-end
-```
-
-Given the example above, the index action will return
-
-```json
-{
- "posts":
- [
- { "title": "Post 1", "body": "Hello!" },
- { "title": "Post 2", "body": "Goodbye!" }
- ]
-}
-```
-
-By default, the root element is the name of the controller. For example, `PostsController`
-generates a root element "posts". To change it:
-
-```ruby
-render json: @posts, root: "some_posts"
-```
-
-You may disable the root element for arrays at the top level, which will result in
-more concise json. See the next section for ways on how to do this. Disabling the
-root element of the array with any of those methods will produce
-
-```json
-[
- { "title": "Post 1", "body": "Hello!" },
- { "title": "Post 2", "body": "Goodbye!" }
-]
-```
-
-To specify a custom serializer for the items within an array:
-
-```ruby
-render json: @posts, each_serializer: FancyPostSerializer
-```
-
-## Disabling the root element
-
-You have 4 options to disable the root element, each with a slightly different scope:
-
-#### 1. Disable root globally for all, or per class
-
-In an initializer:
-
-```ruby
-ActiveSupport.on_load(:active_model_serializers) do
- # Disable for all serializers (except ArraySerializer)
- ActiveModel::Serializer.root = false
-
- # Disable for ArraySerializer
- ActiveModel::ArraySerializer.root = false
-end
-```
-
-#### 2. Disable root per render call in your controller
-
-```ruby
-render json: @posts, root: false
-```
-
-#### 3. Subclass the serializer, and specify using it
-
-```ruby
-class CustomArraySerializer < ActiveModel::ArraySerializer
- self.root = false
-end
-
-# controller:
-render json: @posts, serializer: CustomArraySerializer
-```
-
-#### 4. Define default_serializer_options in your controller
-
-If you define `default_serializer_options` method in your controller,
-all serializers in actions of this controller and it's children will use them.
-One of the options may be `root: false`
-
-```ruby
-def default_serializer_options
- {
- root: false
- }
-end
-```
-
-## Getting the old version
-
-If you find that your project is already relying on the old rails to_json
-change `render :json` to `render json: @your_object.to_json`.
-
-# Attributes and Associations
-
-Once you have a serializer, you can specify which attributes and associations
-you would like to include in the serialized form.
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
- has_many :comments
-end
-```
-
-## Attributes
-
-For specified attributes, a serializer will look up the attribute on the
-object you passed to `render :json`. It uses
-`read_attribute_for_serialization`, which `ActiveRecord` objects implement as a
-regular attribute lookup.
-
-Before looking up the attribute on the object, a serializer will check for the
-presence of a method with the name of the attribute. This allows serializers to
-include properties beyond the simple attributes of the model. For example:
-
-```ruby
-class PersonSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name, :full_name
-
- def full_name
- "#{object.first_name} #{object.last_name}"
- end
-end
-```
-
-Within a serializer's methods, you can access the object being
-serialized as `object`.
-
-Since this shadows any attribute named `object`, you can include them through `object.object`. For example:
-
-```ruby
-class VersionSerializer < ActiveModel::Serializer
- attribute :version_object, key: :object
-
- def version_object
- object.object
- end
-end
-```
-
-You can also access the `current_user` method, which provides an
-authorization context to your serializer. By default, the context
-is the current user of your application, but this
-[can be customized](#customizing-scope).
-
-Serializers will check for the presence of a method named
-`include_[ATTRIBUTE]?` to determine whether a particular attribute should be
-included in the output. This is typically used to customize output
-based on `current_user`. For example:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body, :author
-
- def include_author?
- current_user.admin?
- end
-end
-```
-
-The type of a computed attribute (like :full_name above) is not easily
-calculated without some sophisticated static code analysis. To specify the
-type of a computed attribute:
-
-```ruby
-class PersonSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name, {full_name: :string}
-
- def full_name
- "#{object.first_name} #{object.last_name}"
- end
-end
-```
-
-If you would like the key in the outputted JSON to be different from its name
-in ActiveRecord, you can use the `:key` option to customize it:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :body
-
- # look up :subject on the model, but use +title+ in the JSON
- attribute :subject, key: :title
- has_many :comments
-end
-```
-
-If you would like to add meta information to the outputted JSON, use the `:meta`
-option:
-
-```ruby
-render json: @posts, serializer: CustomArraySerializer, meta: {total: 10}
-```
-
-The above usage of `:meta` will produce the following:
-
-```json
-{
- "meta": { "total": 10 },
- "posts": [
- { "title": "Post 1", "body": "Hello!" },
- { "title": "Post 2", "body": "Goodbye!" }
- ]
-}
-```
-
-If you would like to change the meta key name you can use the `:meta_key` option:
-
-```ruby
-render json: @posts, serializer: CustomArraySerializer, meta: {total: 10}, meta_key: 'meta_object'
-```
-
-The above usage of `:meta_key` will produce the following:
-
-```json
-{
- "meta_object": { "total": 10 },
- "posts": [
- { "title": "Post 1", "body": "Hello!" },
- { "title": "Post 2", "body": "Goodbye!" }
- ]
-}
-```
-
-If you would like direct, low-level control of attribute serialization, you can
-completely override the `attributes` method to return the hash you need:
-
-```ruby
-class PersonSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
-
- def attributes
- hash = super
- if current_user.admin?
- hash["ssn"] = object.ssn
- hash["secret"] = object.mothers_maiden_name
- end
- hash
- end
-end
-```
-
-## Associations
-
-For specified associations, the serializer will look up the association and
-then serialize each element of the association. For instance, a `has_many
-:comments` association will create a new `CommentSerializer` for each comment
-and use it to serialize the comment.
-
-By default, serializers simply look up the association on the original object.
-You can customize this behavior by implementing a method with the name of the
-association and returning a different Array. Often, you will do this to
-customize the objects returned based on the current user.
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
- has_many :comments
-
- # only let the user see comments he created.
- def comments
- object.comments.where(created_by: current_user)
- end
-end
-```
-
-As with attributes, you can change the JSON key that the serializer should
-use for a particular association.
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- # look up comments, but use +my_comments+ as the key in JSON
- has_many :comments, key: :my_comments
-end
-```
-
-Also, as with attributes, serializers will check for the presence
-of a method named `include_[ASSOCIATION]?` to determine whether a particular association
-should be included in the output. For example:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
- has_many :comments
-
- def include_comments?
- !object.comments_disabled?
- end
-end
-```
-
-If you would like lower-level control of association serialization, you can
-override `include_associations!` to specify which associations should be included:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
- has_one :author
- has_many :comments
-
- def include_associations!
- include! :author if current_user.admin?
- include! :comments unless object.comments_disabled?
- end
-end
-```
-
-You may also use the `:serializer` option to specify a custom serializer class and the `:polymorphic` option to specify an association that is polymorphic (STI), e.g.:
-
-```ruby
- has_many :comments, serializer: CommentShortSerializer
- has_one :reviewer, polymorphic: true
-```
-
-Serializers are only concerned with multiplicity, and not ownership. `belongs_to` ActiveRecord associations can be included using `has_one` in your serializer.
-
-## Embedding Associations
-
-By default, associations will be embedded inside the serialized object. So if
-you have a post, the outputted JSON will look like:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comments": [
- { "id": 1, "body": "what a dumb post" }
- ]
- }
-}
-```
-
-This is convenient for simple use-cases, but for more complex clients, it is
-better to supply an Array of IDs for the association. This makes your API more
-flexible from a performance standpoint and avoids wasteful duplication.
-
-To embed IDs instead of associations, simply use the `embed` class method:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- embed :ids
-
- attributes :id, :title, :body
- has_many :comments
-end
-```
-
-Now, any associations will be supplied as an Array of IDs:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comment_ids": [ 1, 2, 3 ]
- }
-}
-```
-
-Alternatively, you can choose to embed only the ids or the associated objects per association:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- attributes :id, :title, :body
-
- has_many :comments, embed: :objects
- has_many :tags, embed: :ids
-end
-```
-
-The JSON will look like this:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comments": [
- { "id": 1, "body": "what a dumb post" }
- ],
- "tag_ids": [ 1, 2, 3 ]
- }
-}
-```
-
-In addition to supplying an Array of IDs, you may want to side-load the data
-alongside the main object. This makes it easier to process the entire package
-of data without having to recursively scan the tree looking for embedded
-information. It also ensures that associations that are shared between several
-objects (like tags), are only delivered once for the entire payload.
-
-You can specify that the data be included like this:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- embed :ids, include: true
-
- attributes :id, :title, :body
- has_many :comments
-end
-```
-
-Assuming that the comments also `has_many :tags`, you will get a JSON like
-this:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comment_ids": [ 1, 2 ]
- },
- "comments": [
- { "id": 1, "body": "what a dumb post", "tag_ids": [ 1, 2 ] },
- { "id": 2, "body": "i liked it", "tag_ids": [ 1, 3 ] },
- ],
- "tags": [
- { "id": 1, "name": "short" },
- { "id": 2, "name": "whiny" },
- { "id": 3, "name": "happy" }
- ]
-}
-```
-
-You can also specify a different root for the embedded objects than the key
-used to reference them:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- embed :ids, include: true
-
- attributes :id, :title, :body
- has_many :comments, key: :comment_ids, root: :comment_objects
-end
-```
-
-This would generate JSON that would look like this:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comment_ids": [ 1 ]
- },
- "comment_objects": [
- { "id": 1, "body": "what a dumb post" }
- ]
-}
-```
-
-You can also specify a different attribute to use rather than the ID of the
-objects:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- embed :ids, include: true
-
- attributes :id, :title, :body
- has_many :comments, embed_key: :external_id
-end
-```
-
-This would generate JSON that would look like this:
-
-```json
-{
- "post": {
- "id": 1,
- "title": "New post",
- "body": "A body!",
- "comment_ids": [ "COMM001" ]
- },
- "comments": [
- { "id": 1, "external_id": "COMM001", "body": "what a dumb post" }
- ]
-}
-```
-
-**NOTE**: The `embed :ids` mechanism is primary useful for clients that process
-data in bulk and load it into a local store. For these clients, the ability to
-easily see all of the data per type, rather than having to recursively scan the
-data looking for information, is extremely useful.
-
-If you are mostly working with the data in simple scenarios and manually making
-Ajax requests, you probably just want to use the default embedded behavior.
-
-## Customizing Scope
-
-In a serializer, `current_user` is the current authorization scope which the controller
-provides to the serializer when you call `render :json`. By default, this is
-`current_user`, but can be customized in your controller by calling
-`serialization_scope`:
-
-```ruby
-class ApplicationController < ActionController::Base
- serialization_scope :current_admin
-end
-```
-
-The above example will also change the scope name from `current_user` to
-`current_admin`.
-
-Please note that, until now, `serialization_scope` doesn't accept a second
-object with options for specifying which actions should or should not take a
-given scope in consideration.
-
-To be clear, it's not possible, yet, to do something like this:
-
-```ruby
-class SomeController < ApplicationController
- serialization_scope :current_admin, except: [:index, :show]
-end
-```
-
-So, in order to have a fine grained control of what each action should take in
-consideration for its scope, you may use something like this:
-
-```ruby
-class CitiesController < ApplicationController
- serialization_scope nil
-
- def index
- @cities = City.all
-
- render json: @cities, each_serializer: CitySerializer
- end
-
- def show
- @city = City.find(params[:id])
-
- render json: @city, scope: current_admin, scope_name: :current_admin
- end
-end
-```
-
-Assuming that the `current_admin` method needs to make a query in the database
-for the current user, the advantage of this approach is that, by setting
-`serialization_scope` to `nil`, the `index` action no longer will need to make
-that query, only the `show` action will.
-
-## Caching
-
-To cache a serializer, call `cached` and define a `cache_key` method:
-
-```ruby
-class PostSerializer < ActiveModel::Serializer
- cached # enables caching for this serializer
-
- attributes :title, :body
-
- def cache_key
- [object, current_user]
- end
-end
-```
-
-The caching interface uses `Rails.cache` under the hood.
-
-# Design and Implementation
-
-## Keep it Simple
-
-ActiveModel::Serializers is capable of producing complex JSON views/large object
-trees, and it may be tempting to design in this way so that your client can make
-fewer requests to get data and so that related querying can be optimized.
-However, keeping things simple in your serializers and controllers may
-significantly reduce complexity and maintenance over the long-term development
-of your application. Please consider reducing the complexity of the JSON views
-you provide via the serializers as you build out your application, so that
-controllers/services can be more easily reused without a lot of complexity
-later.
-
-## Performance
-
-As you develop your controllers or other code that utilizes serializers, try to
-avoid n+1 queries by ensuring that data loads in an optimal fashion, e.g. if you
-are using ActiveRecord, you might want to use query includes or joins as needed
-to make the data available that the serializer(s) need.
diff --git a/Rakefile b/Rakefile
deleted file mode 100644
index 8c5bd75a..00000000
--- a/Rakefile
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env rake
-require "bundler/gem_tasks"
-require "rake/testtask"
-
-desc 'Run tests'
-Rake::TestTask.new(:test) do |t|
- t.libs << 'lib'
- t.libs << 'test'
- t.pattern = 'test/**/*_test.rb'
- t.verbose = true
-end
-
-desc 'Benchmark'
-task :bench do
- load 'bench/perf.rb'
-end
-
-task default: :test
diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec
deleted file mode 100644
index 9b551fad..00000000
--- a/active_model_serializers.gemspec
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- encoding: utf-8 -*-
-
-$:.unshift File.expand_path("../lib", __FILE__)
-require "active_model/serializer/version"
-
-Gem::Specification.new do |gem|
- gem.authors = ["José Valim", "Yehuda Katz"]
- gem.email = ["jose.valim@gmail.com", "wycats@gmail.com"]
- gem.description = %q{Making it easy to serialize models for client-side use}
- gem.summary = %q{Bringing consistency and object orientation to model serialization. Works great for client-side MVC frameworks!}
- gem.homepage = "https://github.com/rails-api/active_model_serializers"
-
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
- gem.files = `git ls-files`.split("\n")
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- gem.name = "active_model_serializers"
- gem.require_paths = ["lib"]
- gem.version = ActiveModel::Serializer::VERSION
-
- gem.required_ruby_version = ">= 1.9.3"
-
- gem.add_dependency "activemodel", ">= 3.2"
-
- gem.add_development_dependency "rails", ">= 3.2"
- gem.add_development_dependency "pry"
- gem.add_development_dependency "simplecov"
- gem.add_development_dependency "coveralls"
-end
diff --git a/bench/perf.rb b/bench/perf.rb
deleted file mode 100644
index ea668d56..00000000
--- a/bench/perf.rb
+++ /dev/null
@@ -1,43 +0,0 @@
-require "rubygems"
-require "bundler/setup"
-require "active_model_serializers"
-require "active_support/json"
-require "benchmark"
-
-class User < Struct.new(:id,:name,:age,:about)
- include ActiveModel::SerializerSupport
-
- def fast_hash
- h = {
- id: read_attribute_for_serialization(:id),
- name: read_attribute_for_serialization(:name),
- about: read_attribute_for_serialization(:about)
- }
- h[:age] = read_attribute_for_serialization(:age) if age > 18
- h
- end
-end
-
-class UserSerializer < ActiveModel::Serializer
- attributes :id, :name, :age, :about
-
- def include_age?
- object.age > 18
- end
-end
-
-
-
-u = User.new(1, "sam", 10, "about")
-s = UserSerializer.new(u)
-
-n = 100000
-
-Benchmark.bmbm {|x|
- x.report("init") { n.times { UserSerializer.new(u) } }
- x.report("fast_hash") { n.times { u.fast_hash } }
- x.report("attributes") { n.times { UserSerializer.new(u).attributes } }
- x.report("serializable_hash") { n.times { UserSerializer.new(u).serializable_hash } }
-}
-
-
diff --git a/cruft.md b/cruft.md
deleted file mode 100644
index 22cbf7d3..00000000
--- a/cruft.md
+++ /dev/null
@@ -1,19 +0,0 @@
-As of Ruby 1.9.3, it is impossible to dynamically generate a Symbol
-through interpolation without generating garbage. Theoretically, Ruby
-should be able to take care of this by building up the String in C and
-interning the C String.
-
-Because of this, we avoid generating dynamic Symbols at runtime. For
-example, instead of generating the instrumentation event dynamically, we
-have a constant with a Hash of events:
-
-```ruby
-INSTRUMENT = {
- serialize: :"serialize.serializer",
- associations: :"associations.serializer"
-}
-```
-
-If Ruby ever fixes this issue and avoids generating garbage with dynamic
-symbols, this code can be removed.
-
diff --git a/lib/action_controller/serialization.rb b/lib/action_controller/serialization.rb
deleted file mode 100644
index 6a67275c..00000000
--- a/lib/action_controller/serialization.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-module ActionController
- # Action Controller Serialization
- #
- # Overrides render :json to check if the given object implements +active_model_serializer+
- # as a method. If so, use the returned serializer instead of calling +to_json+ on the object.
- #
- # This module also provides a serialization_scope method that allows you to configure the
- # +serialization_scope+ of the serializer. Most apps will likely set the +serialization_scope+
- # to the current user:
- #
- # class ApplicationController < ActionController::Base
- # serialization_scope :current_user
- # end
- #
- # If you need more complex scope rules, you can simply override the serialization_scope:
- #
- # class ApplicationController < ActionController::Base
- # private
- #
- # def serialization_scope
- # current_user
- # end
- # end
- #
- module Serialization
- extend ActiveSupport::Concern
-
- include ActionController::Renderers
-
- included do
- class_attribute :_serialization_scope
- self._serialization_scope = :current_user
- end
-
- def serialization_scope
- send(_serialization_scope) if _serialization_scope && respond_to?(_serialization_scope, true)
- end
-
- def default_serializer_options
- end
-
- def _render_option_json(resource, options)
- json = ActiveModel::Serializer.build_json(self, resource, options)
-
- if json
- super(json, options)
- else
- super
- end
- end
-
- module ClassMethods
- def serialization_scope(scope)
- self._serialization_scope = scope
- end
- end
- end
-end
diff --git a/lib/active_model/array_serializer.rb b/lib/active_model/array_serializer.rb
deleted file mode 100644
index e752c812..00000000
--- a/lib/active_model/array_serializer.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-require 'active_model/serializable'
-require 'active_model/serializer/caching'
-require "active_support/core_ext/class/attribute"
-require 'active_support/dependencies'
-require 'active_support/descendants_tracker'
-
-module ActiveModel
- # Active Model Array Serializer
- #
- # Serializes an Array, checking if each element implements
- # the +active_model_serializer+ method.
- #
- # To disable serialization of root elements:
- #
- # ActiveModel::ArraySerializer.root = false
- #
- class ArraySerializer
- extend ActiveSupport::DescendantsTracker
-
- include ActiveModel::Serializable
- include ActiveModel::Serializer::Caching
-
- attr_reader :object, :options
-
- class_attribute :root
-
- class_attribute :cache
- class_attribute :perform_caching
-
- class << self
- # set perform caching like root
- def cached(value = true)
- self.perform_caching = value
- end
- end
-
- def initialize(object, options={})
- @object = object
- @options = options
- end
-
- def serialize_object
- serializable_array
- end
-
- def serializable_array
- object.map do |item|
- if options.has_key? :each_serializer
- serializer = options[:each_serializer]
- elsif item.respond_to?(:active_model_serializer)
- serializer = item.active_model_serializer
- end
- serializer ||= DefaultSerializer
-
- serializable = serializer.new(item, options.merge(root: nil))
-
- if serializable.respond_to?(:serializable_hash)
- serializable.serializable_hash
- else
- serializable.as_json
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializable.rb b/lib/active_model/serializable.rb
deleted file mode 100644
index 7122ae20..00000000
--- a/lib/active_model/serializable.rb
+++ /dev/null
@@ -1,49 +0,0 @@
-require 'active_support/core_ext/object/to_json'
-
-module ActiveModel
- # Enable classes to Classes including this module to serialize themselves by implementing a serialize method and an options method.
- #
- # Example:
- #
- # require 'active_model_serializers'
- #
- # class MySerializer
- # include ActiveModel::Serializable
- #
- # def initialize
- # @options = {}
- # end
- #
- # attr_reader :options
- #
- # def serialize
- # { a: 1 }
- # end
- # end
- #
- # puts MySerializer.new.to_json
- module Serializable
- def as_json(args={})
- if root = args[:root] || options[:root]
- options[:hash] = hash = {}
- options[:unique_values] = {}
-
- hash.merge!(root => serialize)
- include_meta hash
- hash
- else
- serialize
- end
- end
-
- private
-
- def include_meta(hash)
- hash[meta_key] = options[:meta] if options.has_key?(:meta)
- end
-
- def meta_key
- options[:meta_key].try(:to_sym) || :meta
- end
- end
-end
diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb
deleted file mode 100644
index e2a6228b..00000000
--- a/lib/active_model/serializer.rb
+++ /dev/null
@@ -1,475 +0,0 @@
-require 'active_model/serializable'
-require 'active_model/serializer/caching'
-require "active_support/core_ext/class/attribute"
-require "active_support/core_ext/module/anonymous"
-require 'active_support/dependencies'
-require 'active_support/descendants_tracker'
-
-module ActiveModel
- # Active Model Serializer
- #
- # Provides a basic serializer implementation that allows you to easily
- # control how a given object is going to be serialized. On initialization,
- # it expects two objects as arguments, a resource and options. For example,
- # one may do in a controller:
- #
- # PostSerializer.new(@post, scope: current_user).to_json
- #
- # The object to be serialized is the +@post+ and the current user is passed
- # in for authorization purposes.
- #
- # We use the scope to check if a given attribute should be serialized or not.
- # For example, some attributes may only be returned if +current_user+ is the
- # author of the post:
- #
- # class PostSerializer < ActiveModel::Serializer
- # attributes :title, :body
- # has_many :comments
- #
- # private
- #
- # def attributes
- # hash = super
- # hash.merge!(email: post.email) if author?
- # hash
- # end
- #
- # def author?
- # post.author == scope
- # end
- # end
- #
- class Serializer
- extend ActiveSupport::DescendantsTracker
-
- include ActiveModel::Serializable
- include ActiveModel::Serializer::Caching
-
- INCLUDE_METHODS = {}
- INSTRUMENT = { serialize: :"serialize.serializer", associations: :"associations.serializer" }
-
- class IncludeError < StandardError
- attr_reader :source, :association
-
- def initialize(source, association)
- @source, @association = source, association
- end
-
- def to_s
- "Cannot serialize #{association} when #{source} does not have a root!"
- end
- end
-
- class_attribute :_attributes
- self._attributes = {}
-
- class_attribute :_associations
- self._associations = {}
-
- class_attribute :_root
- class_attribute :_embed
- self._embed = :objects
- class_attribute :_root_embed
-
- class_attribute :cache
- class_attribute :perform_caching
-
- class << self
- def cached(value = true)
- self.perform_caching = value
- end
-
- # Define attributes to be used in the serialization.
- def attributes(*attrs)
-
- self._attributes = _attributes.dup
-
- attrs.each do |attr|
- if Hash === attr
- attr.each {|attr_real, key| attribute(attr_real, key: key) }
- else
- attribute attr
- end
- end
- end
-
- def attribute(attr, options={})
- self._attributes = _attributes.merge(attr.is_a?(Hash) ? attr : {attr => options[:key] || attr.to_s.gsub(/\?$/, '').to_sym})
-
- attr = attr.keys[0] if attr.is_a? Hash
-
- unless method_defined?(attr)
- define_method attr do
- object.read_attribute_for_serialization(attr.to_sym)
- end
- end
-
- define_include_method attr
-
- # protect inheritance chains and open classes
- # if a serializer inherits from another OR
- # attributes are added later in a classes lifecycle
- # poison the cache
- define_method :_fast_attributes do
- raise NameError
- end
-
- end
-
- def associate(klass, attrs) #:nodoc:
- options = attrs.extract_options!
- self._associations = _associations.dup
-
- attrs.each do |attr|
- unless method_defined?(attr)
- define_method attr do
- object.send attr
- end
- end
-
- define_include_method attr
-
- self._associations[attr] = [klass, options]
- end
- end
-
- def define_include_method(name)
- method = "include_#{name}?".to_sym
-
- INCLUDE_METHODS[name] = method
-
- unless method_defined?(method)
- define_method method do
- true
- end
- end
- end
-
- # Defines an association in the object should be rendered.
- #
- # The serializer object should implement the association name
- # as a method which should return an array when invoked. If a method
- # with the association name does not exist, the association name is
- # dispatched to the serialized object.
- def has_many(*attrs)
- associate(Association::HasMany, attrs)
- end
-
- # Defines an association in the object should be rendered.
- #
- # The serializer object should implement the association name
- # as a method which should return an object when invoked. If a method
- # with the association name does not exist, the association name is
- # dispatched to the serialized object.
- def has_one(*attrs)
- associate(Association::HasOne, attrs)
- end
-
- # 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, options)|
- association = association_class.new(attr, options)
-
- 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
-
- # Define how associations should be embedded.
- #
- # embed :objects # Embed associations as full objects
- # embed :ids # Embed only the association ids
- # embed :ids, include: true # Embed the association ids and include objects in the root
- #
- def embed(type, options={})
- self._embed = type
- self._root_embed = true if options[:include]
- end
-
- # Defines the root used on serialization. If false, disables the root.
- def root(name)
- self._root = name
- end
- alias_method :root=, :root
-
- # Used internally to create a new serializer object based on controller
- # settings and options for a given resource. These settings are typically
- # set during the request lifecycle or by the controller class, and should
- # not be manually defined for this method.
- def build_json(controller, resource, options)
- default_options = controller.send(:default_serializer_options) || {}
- options = default_options.merge(options || {})
-
- serializer = options.delete(:serializer) ||
- (resource.respond_to?(:active_model_serializer) &&
- resource.active_model_serializer)
-
- return serializer unless serializer
-
- if resource.respond_to?(:to_ary)
- unless serializer <= ActiveModel::ArraySerializer
- raise ArgumentError.new("#{serializer.name} is not an ArraySerializer. " +
- "You may want to use the :each_serializer option instead.")
- end
-
- if options[:root] != false && serializer.root != false
- # the serializer for an Array is ActiveModel::ArraySerializer
- options[:root] ||= serializer.root || controller.controller_name
- end
- end
-
- options[:scope] = controller.serialization_scope unless options.has_key?(:scope)
- options[:scope_name] = controller._serialization_scope unless options.has_key?(:scope_name)
- options[:url_options] = controller.url_options
-
- serializer.new(resource, options)
- end
- end
-
- attr_reader :object, :options
-
- def initialize(object, options={})
- @object, @options = object, options
-
- scope_name = @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 root_name
- return false if self._root == false
-
- class_name = self.class.name.demodulize.underscore.sub(/_serializer$/, '').to_sym unless self.class.name.blank?
-
- if self._root == true
- class_name
- else
- self._root || class_name
- end
- end
-
- def url_options
- @options[:url_options] || {}
- end
-
- # Returns a json representation of the serializable
- # object including the root.
- def as_json(args={})
- super(root: args.fetch(:root, options.fetch(:root, root_name)))
- end
-
- def serialize_object
- serializable_hash
- end
-
- # Returns a hash representation of the serializable
- # object without the root.
- def serializable_hash
- return nil if @object.nil?
- @node = attributes
- include_associations! if _embed
- @node
- end
-
- def include_associations!
- _associations.each_key do |name|
- include!(name) if include?(name)
- end
- end
-
- def include?(name)
- return false if @options.key?(:only) && !Array(@options[:only]).include?(name)
- return false if @options.key?(:except) && Array(@options[:except]).include?(name)
- send INCLUDE_METHODS[name]
- end
-
- def include!(name, options={})
- hash = @options[:hash]
- unique_values = @options[:unique_values] ||= {}
-
- node = options[:node] ||= @node
- value = options[:value]
-
- if options[:include] == nil
- if @options.key?(:include)
- options[:include] = @options[:include].include?(name)
- elsif @options.include?(:exclude)
- options[:include] = !@options[:exclude].include?(name)
- end
- end
-
- klass, klass_options = _associations[name]
- association_class =
- if klass
- options = klass_options.merge options
- klass
- elsif value.respond_to?(:to_ary)
- Association::HasMany
- else
- Association::HasOne
- end
-
- options = default_embed_options.merge!(options)
- options[:value] ||= send(name)
- association = association_class.new(name, options, self.options)
-
- if association.embed_ids?
- node[association.key] = association.serialize_ids
-
- if association.embed_in_root? && hash.nil?
- raise IncludeError.new(self.class, association.name)
- elsif association.embed_in_root? && association.embeddable?
- merge_association hash, association.root, association.serializables, unique_values
- end
- elsif association.embed_objects?
- node[association.key] = association.serialize
- end
- end
-
- # In some cases, an Array of associations is built by merging the associated
- # content for all of the children. For instance, if a Post has_many comments,
- # which has_many tags, the top-level :tags key will contain the merged list
- # of all tags for all comments of the post.
- #
- # In order to make this efficient, we store a :unique_values hash containing
- # a unique list of all of the objects that are already in the Array. This
- # avoids the need to scan through the Array looking for entries every time
- # we want to merge a new list of values.
- def merge_association(hash, key, serializables, unique_values)
- already_serialized = (unique_values[key] ||= {})
- serializable_hashes = (hash[key] ||= [])
-
- serializables.each do |serializable|
- unless already_serialized.include? serializable.object
- already_serialized[serializable.object] = true
- serializable_hashes << serializable.serializable_hash
- end
- end
- end
-
- # Returns a hash representation of the serializable
- # object attributes.
- def attributes
- _fast_attributes
- rescue NameError
- method = "def _fast_attributes\n"
-
- method << " h = {}\n"
-
- _attributes.each do |name,key|
- method << " h[:\"#{key}\"] = read_attribute_for_serialization(:\"#{name}\") if include?(:\"#{name}\")\n"
- end
- method << " h\nend"
-
- self.class.class_eval method
- _fast_attributes
- end
-
- # Returns options[:scope]
- def scope
- @options[:scope]
- end
-
- alias :read_attribute_for_serialization :send
-
- # Use ActiveSupport::Notifications to send events to external systems.
- # The event name is: name.class_name.serializer
- def instrument(name, payload = {}, &block)
- event_name = INSTRUMENT[name]
- ActiveSupport::Notifications.instrument(event_name, payload, &block)
- end
-
- private
-
- def default_embed_options
- {
- embed: _embed,
- include: _root_embed
- }
- end
- end
-
- # DefaultSerializer
- #
- # Provides a constant interface for all items, particularly
- # for ArraySerializer.
- class DefaultSerializer
- attr_reader :object, :options
-
- def initialize(object, options={})
- @object, @options = object, options
- end
-
- def serializable_hash
- @object.as_json(@options)
- end
- end
-end
diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb
deleted file mode 100644
index 1f2b0b53..00000000
--- a/lib/active_model/serializer/associations.rb
+++ /dev/null
@@ -1,185 +0,0 @@
-module ActiveModel
- class Serializer
- class Association #:nodoc:
- # name: The name of the association.
- #
- # options: A hash. These keys are accepted:
- #
- # value: The object we're associating with.
- #
- # serializer: The class used to serialize the association.
- #
- # embed: Define how associations should be embedded.
- # - :objects # Embed associations as full objects.
- # - :ids # Embed only the association ids.
- # - :ids, include: true # Embed the association ids and include objects in the root.
- #
- # include: Used in conjunction with embed :ids. Includes the objects in the root.
- #
- # root: Used in conjunction with include: true. Defines the key used to embed the objects.
- #
- # key: Key name used to store the ids in.
- #
- # embed_key: Method used to fetch ids. Defaults to :id.
- #
- # polymorphic: Is the association is polymorphic?. Values: true or false.
- def initialize(name, options={}, serializer_options={})
- @name = name
- @object = options[:value]
-
- embed = options[:embed]
- @embed_ids = embed == :id || embed == :ids
- @embed_objects = embed == :object || embed == :objects
- @embed_key = options[:embed_key] || :id
- @embed_in_root = options[:include]
-
- serializer = options[:serializer]
- @serializer_class = serializer.is_a?(String) ? serializer.constantize : serializer
-
- @options = options
- @serializer_options = serializer_options
- end
-
- attr_reader :object, :root, :name, :embed_ids, :embed_objects, :embed_in_root
- alias embeddable? object
- alias embed_objects? embed_objects
- alias embed_ids? embed_ids
- alias use_id_key? embed_ids?
- alias embed_in_root? embed_in_root
-
- def key
- if key = options[:key]
- key
- elsif use_id_key?
- id_key
- else
- name
- end
- end
-
- private
-
- attr_reader :embed_key, :serializer_class, :options, :serializer_options
-
- def find_serializable(object)
- if serializer_class
- serializer_class.new(object, serializer_options)
- elsif object.respond_to?(:active_model_serializer) && (ams = object.active_model_serializer)
- ams.new(object, serializer_options)
- else
- object
- end
- end
-
- class HasMany < Association #:nodoc:
- def root
- options[:root] || name
- end
-
- def id_key
- "#{name.to_s.singularize}_ids".to_sym
- end
-
- def serializables
- object.map do |item|
- find_serializable(item)
- end
- end
-
- def serialize
- object.map do |item|
- find_serializable(item).serializable_hash
- end
- end
-
- def serialize_ids
- object.map do |item|
- serializer = find_serializable(item)
- if serializer.respond_to?(embed_key)
- serializer.send(embed_key)
- else
- item.read_attribute_for_serialization(embed_key)
- end
- end
- end
- end
-
- class HasOne < Association #:nodoc:
- def initialize(name, options={}, serializer_options={})
- super
- @polymorphic = options[:polymorphic]
- end
-
- def root
- if root = options[:root]
- root
- elsif polymorphic?
- object.class.to_s.pluralize.demodulize.underscore.to_sym
- else
- name.to_s.pluralize.to_sym
- end
- end
-
- def id_key
- "#{name}_id".to_sym
- end
-
- def embeddable?
- super || !polymorphic?
- end
-
- def serializables
- value = object && find_serializable(object)
- value ? [value] : []
- end
-
- def serialize
- if object
- if polymorphic?
- {
- :type => polymorphic_key,
- polymorphic_key => find_serializable(object).serializable_hash
- }
- else
- find_serializable(object).serializable_hash
- end
- end
- end
-
- def serialize_ids
- if object
- serializer = find_serializable(object)
- id =
- if serializer.respond_to?(embed_key)
- serializer.send(embed_key)
- else
- object.read_attribute_for_serialization(embed_key)
- end
-
- if polymorphic?
- {
- type: polymorphic_key,
- id: id
- }
- else
- id
- end
- end
- end
-
- private
-
- attr_reader :polymorphic
- alias polymorphic? polymorphic
-
- def use_id_key?
- embed_ids? && !polymorphic?
- end
-
- def polymorphic_key
- object.class.to_s.demodulize.underscore.to_sym
- end
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/caching.rb b/lib/active_model/serializer/caching.rb
deleted file mode 100644
index 50fcf7b5..00000000
--- a/lib/active_model/serializer/caching.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module ActiveModel
- class Serializer
- module Caching
- def to_json(*args)
- if caching_enabled?
- key = expand_cache_key([self.class.to_s.underscore, cache_key, 'to-json'])
- cache.fetch key do
- super
- end
- else
- super
- end
- end
-
- def serialize(*args)
- if caching_enabled?
- key = expand_cache_key([self.class.to_s.underscore, cache_key, 'serialize'])
- cache.fetch key do
- serialize_object
- end
- else
- serialize_object
- end
- end
-
- private
-
- def caching_enabled?
- perform_caching && cache && respond_to?(:cache_key)
- end
-
- def expand_cache_key(*args)
- ActiveSupport::Cache.expand_cache_key(args)
- end
- end
- end
-end
diff --git a/lib/active_model/serializer/version.rb b/lib/active_model/serializer/version.rb
deleted file mode 100644
index 10e62668..00000000
--- a/lib/active_model/serializer/version.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-module ActiveModel
- class Serializer
- VERSION = "0.8.1"
- end
-end
diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb
deleted file mode 100644
index 4ae2d743..00000000
--- a/lib/active_model_serializers.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-require "active_support"
-require "active_support/core_ext/string/inflections"
-require "active_support/notifications"
-require "active_model"
-require "active_model/array_serializer"
-require "active_model/serializer"
-require "active_model/serializer/associations"
-require "set"
-
-if defined?(Rails)
- module ActiveModel
- class Railtie < Rails::Railtie
- generators do |app|
- Rails::Generators.configure!(app.config.generators)
- Rails::Generators.hidden_namespaces.uniq!
- require_relative "generators/resource_override"
- end
-
- initializer "include_routes.active_model_serializer" do |app|
- ActiveSupport.on_load(:active_model_serializers) do
- include AbstractController::UrlFor
- extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
- include app.routes.mounted_helpers
- end
- end
-
- initializer "caching.active_model_serializer" do |app|
- ActiveModel::Serializer.perform_caching = app.config.action_controller.perform_caching
- ActiveModel::ArraySerializer.perform_caching = app.config.action_controller.perform_caching
-
- ActiveModel::Serializer.cache = Rails.cache
- ActiveModel::ArraySerializer.cache = Rails.cache
- end
- end
- end
-end
-
-module ActiveModel::SerializerSupport
- extend ActiveSupport::Concern
-
- module ClassMethods #:nodoc:
- if "".respond_to?(:safe_constantize)
- def active_model_serializer
- "#{self.name}Serializer".safe_constantize
- end
- else
- def active_model_serializer
- begin
- "#{self.name}Serializer".constantize
- rescue NameError => e
- raise unless e.message =~ /uninitialized constant/
- end
- end
- end
- end
-
- # Returns a model serializer for this object considering its namespace.
- def active_model_serializer
- self.class.active_model_serializer
- end
-
- alias :read_attribute_for_serialization :send
-end
-
-module ActiveModel::ArraySerializerSupport
- def active_model_serializer
- ActiveModel::ArraySerializer
- end
-end
-
-Array.send(:include, ActiveModel::ArraySerializerSupport)
-Set.send(:include, ActiveModel::ArraySerializerSupport)
-
-{
- active_record: 'ActiveRecord::Relation',
- mongoid: 'Mongoid::Criteria'
-}.each do |orm, rel_class|
- ActiveSupport.on_load(orm) do
- include ActiveModel::SerializerSupport
- rel_class.constantize.send(:include, ActiveModel::ArraySerializerSupport)
- end
-end
-
-begin
- require 'action_controller'
- require 'action_controller/serialization'
-
- ActiveSupport.on_load(:action_controller) do
- include ::ActionController::Serialization
- end
-rescue LoadError => ex
- # rails on installed, continuing
-end
-
-ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
diff --git a/lib/active_record/serializer_override.rb b/lib/active_record/serializer_override.rb
deleted file mode 100644
index b6149b83..00000000
--- a/lib/active_record/serializer_override.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# We do not recommend that you use AM::S in this way, but if you must, here
-# is a mixin that overrides ActiveRecord::Base#to_json and #as_json.
-
-module ActiveRecord
- module SerializerOverride
- def to_json options = {}
- active_model_serializer.new(self).to_json options
- end
-
- def as_json options={}
- active_model_serializer.new(self).as_json options
- end
- end
-
- Base.send(:include, SerializerOverride)
-end
diff --git a/lib/generators/resource_override.rb b/lib/generators/resource_override.rb
deleted file mode 100644
index 1b48a12e..00000000
--- a/lib/generators/resource_override.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require "rails/generators"
-require "rails/generators/rails/resource/resource_generator"
-
-module Rails
- module Generators
- ResourceGenerator.class_eval do
- def add_serializer
- invoke "serializer"
- end
- end
- end
-end
-
diff --git a/lib/generators/serializer/USAGE b/lib/generators/serializer/USAGE
deleted file mode 100644
index a49f7ea1..00000000
--- a/lib/generators/serializer/USAGE
+++ /dev/null
@@ -1,9 +0,0 @@
-Description:
- Generates a serializer for the given resource with tests.
-
-Example:
- `rails generate serializer Account name created_at`
-
- For TestUnit it creates:
- Serializer: app/serializers/account_serializer.rb
- TestUnit: test/unit/account_serializer_test.rb
diff --git a/lib/generators/serializer/serializer_generator.rb b/lib/generators/serializer/serializer_generator.rb
deleted file mode 100644
index 8212d62c..00000000
--- a/lib/generators/serializer/serializer_generator.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-module Rails
- module Generators
- class SerializerGenerator < NamedBase
- source_root File.expand_path("../templates", __FILE__)
- check_class_collision suffix: "Serializer"
-
- argument :attributes, type: :array, default: [], banner: "field:type field:type"
-
- class_option :parent, type: :string, desc: "The parent class for the generated serializer"
-
- def create_serializer_file
- template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
- end
-
- private
-
- def attributes_names
- [:id] + attributes.select { |attr| !attr.reference? }.map { |a| a.name.to_sym }
- end
-
- def association_names
- attributes.select { |attr| attr.reference? }.map { |a| a.name.to_sym }
- end
-
- def parent_class_name
- if options[:parent]
- options[:parent]
- elsif defined?(::ApplicationSerializer)
- "ApplicationSerializer"
- else
- "ActiveModel::Serializer"
- end
- end
- end
- end
-end
diff --git a/lib/generators/serializer/templates/serializer.rb b/lib/generators/serializer/templates/serializer.rb
deleted file mode 100644
index 4ebb004e..00000000
--- a/lib/generators/serializer/templates/serializer.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-<% module_namespacing do -%>
-class <%= class_name %>Serializer < <%= parent_class_name %>
- attributes <%= attributes_names.map(&:inspect).join(", ") %>
-<% association_names.each do |attribute| -%>
- has_one :<%= attribute %>
-<% end -%>
-end
-<% end -%>
diff --git a/test/array_serializer_test.rb b/test/array_serializer_test.rb
deleted file mode 100644
index d48e8027..00000000
--- a/test/array_serializer_test.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-require "test_helper"
-require "test_fakes"
-
-class ArraySerializerTest < ActiveModel::TestCase
- # serialize different typed objects
- def test_array_serializer
- model = Model.new
- user = User.new
- comments = Comment.new(title: "Comment1", id: 1)
-
- array = [model, user, comments]
- serializer = array.active_model_serializer.new(array, scope: { scope: true })
- assert_equal([
- { model: "Model" },
- { last_name: "Valim", ok: true, first_name: "Jose", scope: true },
- { title: "Comment1" }
- ], serializer.as_json)
- end
-
- def test_array_serializer_with_root
- comment1 = Comment.new(title: "Comment1", id: 1)
- comment2 = Comment.new(title: "Comment2", id: 2)
-
- array = [ comment1, comment2 ]
-
- serializer = array.active_model_serializer.new(array, root: :comments)
-
- assert_equal({ comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]}, serializer.as_json)
- end
-
- def test_active_model_with_root
- comment1 = ModelWithActiveModelSerializer.new(title: "Comment1")
- comment2 = ModelWithActiveModelSerializer.new(title: "Comment2")
-
- array = [ comment1, comment2 ]
-
- serializer = array.active_model_serializer.new(array, root: :comments)
-
- assert_equal({ comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]}, serializer.as_json)
- end
-
- def test_array_serializer_with_hash
- hash = { value: "something" }
- array = [hash]
- serializer = array.active_model_serializer.new(array, root: :items)
- assert_equal({ items: [hash.as_json] }, serializer.as_json)
- end
-
- def test_array_serializer_with_specified_serializer
- post1 = Post.new(title: "Post1", author: "Author1", id: 1)
- post2 = Post.new(title: "Post2", author: "Author2", id: 2)
-
- array = [ post1, post2 ]
-
- serializer = array.active_model_serializer.new array, each_serializer: CustomPostSerializer
-
- assert_equal([
- { title: "Post1" },
- { title: "Post2" }
- ], serializer.as_json)
- end
-
- def test_array_serializer_using_default_serializer
- hash = { "value" => "something" }
- class << hash
- def active_model_serializer
- nil
- end
- end
-
- array = [hash]
-
- serializer = array.active_model_serializer.new array
-
- assert_equal([
- { "value" => "something" }
- ], serializer.as_json)
- end
-end
diff --git a/test/association_test.rb b/test/association_test.rb
deleted file mode 100644
index 3ae225a0..00000000
--- a/test/association_test.rb
+++ /dev/null
@@ -1,592 +0,0 @@
-require "test_helper"
-
-class AssociationTest < ActiveModel::TestCase
- def def_serializer(&block)
- Class.new(ActiveModel::Serializer, &block)
- end
-
- class Model
- def initialize(hash={})
- @attributes = hash
- end
-
- def read_attribute_for_serialization(name)
- @attributes[name]
- end
-
- def as_json(*)
- { model: "Model" }
- end
-
- def method_missing(meth, *args)
- if meth.to_s =~ /^(.*)=$/
- @attributes[$1.to_sym] = args[0]
- elsif @attributes.key?(meth)
- @attributes[meth]
- else
- super
- end
- end
- end
-
- def setup
- @hash = {}
- @root_hash = {}
-
- @post = Model.new(title: "New Post", body: "Body")
- @comment = Model.new(id: 1, external_id: "COMM001", body: "ZOMG A COMMENT")
- @post.comments = [ @comment ]
- @post.comment = @comment
-
- @comment_serializer_class = def_serializer do
- attributes :id, :external_id, :body
- end
-
- @post_serializer_class = def_serializer do
- attributes :title, :body
- end
-
- @post_serializer = @post_serializer_class.new(@post, hash: @root_hash)
- end
-
- def include!(key, options={})
- @post_serializer.include! key, {
- embed: :ids,
- include: true,
- node: @hash,
- serializer: @comment_serializer_class
- }.merge(options)
- end
-
- def include_bare!(key, options={})
- @post_serializer.include! key, {
- node: @hash,
- serializer: @comment_serializer_class
- }.merge(options)
- end
-
- class NoDefaults < AssociationTest
- def test_include_bang_has_many_associations
- include! :comments, value: @post.comments
-
- assert_equal({
- comment_ids: [ 1 ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_include_bang_with_embed_false
- include! :comments, value: @post.comments, embed: false
-
- assert_equal({}, @hash)
- assert_equal({}, @root_hash)
- end
-
- def test_include_bang_with_embed_ids_include_false
- include! :comments, value: @post.comments, embed: :ids, include: false
-
- assert_equal({
- comment_ids: [ 1 ]
- }, @hash)
-
- assert_equal({}, @root_hash)
- end
-
- def test_include_bang_has_one_associations
- include! :comment, value: @post.comment
-
- assert_equal({
- comment_id: 1
- }, @hash)
-
- assert_equal({
- comments: [{ id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }]
- }, @root_hash)
- end
- end
-
- class DefaultsTest < AssociationTest
- def test_with_default_has_many
- @post_serializer_class.class_eval do
- has_many :comments
- end
-
- include! :comments
-
- assert_equal({
- comment_ids: [ 1 ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_one
- @post_serializer_class.class_eval do
- has_one :comment
- end
-
- include! :comment
-
- assert_equal({
- comment_id: 1
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_many_with_custom_key
- @post_serializer_class.class_eval do
- has_many :comments, key: :custom_comments
- end
-
- include! :comments
-
- assert_equal({
- custom_comments: [ 1 ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_one_with_custom_key
- @post_serializer_class.class_eval do
- has_one :comment, key: :custom_comment_id
- end
-
- include! :comment
-
- assert_equal({
- custom_comment_id: 1
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_many_with_custom_embed_key
- @post_serializer_class.class_eval do
- has_many :comments, embed_key: :external_id
- end
-
- include! :comments
-
- assert_equal({
- comment_ids: [ "COMM001" ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_one_with_custom_embed_key
- @post_serializer_class.class_eval do
- has_one :comment, embed_key: :external_id
- end
-
- include! :comment
-
- assert_equal({
- comment_id: "COMM001"
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_many_with_custom_key_and_custom_embed_key
- @post_serializer_class.class_eval do
- has_many :comments, key: :custom_comments, embed_key: :external_id
- end
-
- include! :comments
-
- assert_equal({
- custom_comments: [ "COMM001" ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_with_default_has_one_with_custom_key_and_custom_embed_key
- @post_serializer_class.class_eval do
- has_one :comment, key: :custom_comment, embed_key: :external_id
- end
-
- include! :comment
-
- assert_equal({
- custom_comment: "COMM001"
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_embed_objects_for_has_many_associations
- @post_serializer_class.class_eval do
- has_many :comments, embed: :objects
- end
-
- include_bare! :comments
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @hash)
-
- assert_equal({}, @root_hash)
- end
-
- def test_embed_ids_for_has_many_associations
- @post_serializer_class.class_eval do
- has_many :comments, embed: :ids
- end
-
- include_bare! :comments
-
- assert_equal({
- comment_ids: [ 1 ]
- }, @hash)
-
- assert_equal({}, @root_hash)
- end
-
- def test_embed_false_for_has_many_associations
- @post_serializer_class.class_eval do
- has_many :comments, embed: false
- end
-
- include_bare! :comments
-
- assert_equal({}, @hash)
- assert_equal({}, @root_hash)
- end
-
- def test_embed_ids_include_true_for_has_many_associations
- @post_serializer_class.class_eval do
- has_many :comments, embed: :ids, include: true
- end
-
- include_bare! :comments
-
- assert_equal({
- comment_ids: [ 1 ]
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_embed_ids_for_has_one_associations
- @post_serializer_class.class_eval do
- has_one :comment, embed: :ids
- end
-
- include_bare! :comment
-
- assert_equal({
- comment_id: 1
- }, @hash)
-
- assert_equal({}, @root_hash)
- end
-
- def test_embed_false_for_has_one_associations
- @post_serializer_class.class_eval do
- has_one :comment, embed: false
- end
-
- include_bare! :comment
-
- assert_equal({}, @hash)
- assert_equal({}, @root_hash)
- end
-
- def test_embed_ids_include_true_for_has_one_associations
- @post_serializer_class.class_eval do
- has_one :comment, embed: :ids, include: true
- end
-
- include_bare! :comment
-
- assert_equal({
- comment_id: 1
- }, @hash)
-
- assert_equal({
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, @root_hash)
- end
-
- def test_embed_ids_include_true_does_not_serialize_multiple_times
- @post.recent_comment = @comment
-
- @post_serializer_class.class_eval do
- has_one :comment, embed: :ids, include: true
- has_one :recent_comment, embed: :ids, include: true, root: :comments
- end
-
- # Count how often the @comment record is serialized.
- serialized_times = 0
- @comment.class_eval do
- define_method :read_attribute_for_serialization, lambda { |name|
- serialized_times += 1 if name == :body
- super(name)
- }
- end
-
- include_bare! :comment
- include_bare! :recent_comment
-
- assert_equal 1, serialized_times
- end
-
- def test_include_with_read_association_id_for_serialization_hook
- @post_serializer_class.class_eval do
- has_one :comment, embed: :ids, include: true
- end
-
- association_name = nil
- @post.class_eval do
- define_method :read_attribute_for_serialization, lambda { |name|
- association_name = name
- send(name)
- }
- define_method :comment_id, lambda {
- @attributes[:comment].id
- }
- end
-
- include_bare! :comment
-
- assert_equal({
- comment_id: 1
- }, @hash)
- end
-
- def test_include_with_read_association_ids_for_serialization_hook
- @post_serializer_class.class_eval do
- has_many :comments, embed: :ids, include: false
- end
-
- association_name = nil
- @post.class_eval do
- define_method :read_attribute_for_serialization, lambda { |name|
- association_name = name
- send(name)
- }
- define_method :comment_ids, lambda {
- @attributes[:comments].map(&:id)
- }
- end
-
- include_bare! :comments
-
- assert_equal({
- comment_ids: [1]
- }, @hash)
- end
- end
-
- class RecursiveTest < AssociationTest
- class BarSerializer < ActiveModel::Serializer; end
-
- class FooSerializer < ActiveModel::Serializer
- root :foos
- attributes :id
- has_many :bars, serializer: BarSerializer, root: :bars, embed: :ids, include: true
- end
-
- class BarSerializer < ActiveModel::Serializer
- root :bars
- attributes :id
- has_many :foos, serializer: FooSerializer, root: :foos, embed: :ids, include: true
- end
-
- class Foo < Model
- def active_model_serializer; FooSerializer; end
- end
-
- class Bar < Model
- def active_model_serializer; BarSerializer; end
- end
-
- def setup
- super
-
- foo = Foo.new(id: 1)
- bar = Bar.new(id: 2)
-
- foo.bars = [ bar ]
- bar.foos = [ foo ]
-
- collection = [ foo ]
-
- @serializer = collection.active_model_serializer.new(collection, root: :foos)
- end
-
- def test_mutual_relation_result
- assert_equal({
- foos: [{
- bar_ids: [ 2 ],
- id: 1
- }],
- bars: [{
- foo_ids: [ 1 ],
- id: 2
- }]
- }, @serializer.as_json)
- end
-
- def test_mutual_relation_does_not_raise_error
- assert_nothing_raised SystemStackError, 'stack level too deep' do
- @serializer.as_json
- end
- end
- end
-
- class InclusionTest < AssociationTest
- def setup
- super
-
- comment_serializer_class = @comment_serializer_class
-
- @post_serializer_class.class_eval do
- root :post
- embed :ids, include: true
- has_many :comments, serializer: comment_serializer_class
- end
- end
-
- def test_when_it_is_included
- post_serializer = @post_serializer_class.new(
- @post, include: [:comments]
- )
-
- json = post_serializer.as_json
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body",
- comment_ids: [ 1 ]
- },
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, json)
- end
-
- def test_when_it_is_not_included
- post_serializer = @post_serializer_class.new(
- @post, include: []
- )
-
- json = post_serializer.as_json
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body",
- comment_ids: [ 1 ]
- }
- }, json)
- end
-
- def test_when_it_is_excluded
- post_serializer = @post_serializer_class.new(
- @post, exclude: [:comments]
- )
-
- json = post_serializer.as_json
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body",
- comment_ids: [ 1 ]
- }
- }, json)
- end
-
- def test_when_it_is_not_excluded
- post_serializer = @post_serializer_class.new(
- @post, exclude: []
- )
-
- json = post_serializer.as_json
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body",
- comment_ids: [ 1 ]
- },
- comments: [
- { id: 1, external_id: "COMM001", body: "ZOMG A COMMENT" }
- ]
- }, json)
- end
- end
-
- class StringSerializerOption < AssociationTest
- class StringSerializer < ActiveModel::Serializer
- attributes :id, :body
- end
-
- def test_specifying_serializer_class_as_string
- @post_serializer_class.class_eval do
- has_many :comments, embed: :objects
- end
-
- include_bare! :comments, serializer: "AssociationTest::StringSerializerOption::StringSerializer"
-
- assert_equal({
- comments: [
- { id: 1, body: "ZOMG A COMMENT" }
- ]
- }, @hash)
-
- assert_equal({}, @root_hash)
- end
- end
-end
diff --git a/test/caching_test.rb b/test/caching_test.rb
deleted file mode 100644
index ee1dd263..00000000
--- a/test/caching_test.rb
+++ /dev/null
@@ -1,96 +0,0 @@
-require "test_helper"
-
-class CachingTest < ActiveModel::TestCase
- class NullStore
- def fetch(key)
- return store[key] if store[key]
-
- store[key] = yield
- end
-
- def clear
- store.clear
- end
-
- def store
- @store ||= {}
- end
-
- def read(key)
- store[key]
- end
- end
-
- class Programmer
- def name
- 'Adam'
- end
-
- def skills
- %w(ruby)
- end
-
- def read_attribute_for_serialization(name)
- send name
- end
- end
-
- def test_serializers_have_a_cache_store
- ActiveModel::Serializer.cache = NullStore.new
-
- assert_kind_of NullStore, ActiveModel::Serializer.cache
- end
-
- def test_serializers_can_enable_caching
- serializer = Class.new(ActiveModel::Serializer) do
- cached true
- end
-
- assert serializer.perform_caching
- end
-
- def test_serializers_use_cache
- serializer = Class.new(ActiveModel::Serializer) do
- cached true
- attributes :name, :skills
-
- def self.to_s
- 'serializer'
- end
-
- def cache_key
- object.name
- end
- end
-
- serializer.cache = NullStore.new
- instance = serializer.new Programmer.new
-
- instance.to_json
-
- assert_equal(instance.serializable_hash, serializer.cache.read('serializer/Adam/serialize'))
- assert_equal(instance.to_json, serializer.cache.read('serializer/Adam/to-json'))
- end
-
- def test_array_serializer_uses_cache
- serializer = Class.new(ActiveModel::ArraySerializer) do
- cached true
-
- def self.to_s
- 'array_serializer'
- end
-
- def cache_key
- 'cache-key'
- end
- end
-
- serializer.cache = NullStore.new
- instance = serializer.new [Programmer.new]
-
- instance.to_json
-
- assert_equal instance.serializable_array, serializer.cache.read('array_serializer/cache-key/serialize')
- assert_equal instance.to_json, serializer.cache.read('array_serializer/cache-key/to-json')
- end
-end
diff --git a/test/generators_test.rb b/test/generators_test.rb
deleted file mode 100644
index b1a05b3a..00000000
--- a/test/generators_test.rb
+++ /dev/null
@@ -1,73 +0,0 @@
-require 'test_helper'
-
-class Foo < Rails::Application
- if Rails.version.to_s.start_with? '4'
- config.eager_load = false
- config.secret_key_base = 'abc123'
- end
-end
-
-Rails.application.load_generators
-
-require 'generators/serializer/serializer_generator'
-
-class SerializerGeneratorTest < Rails::Generators::TestCase
- destination File.expand_path("../tmp", __FILE__)
- setup :prepare_destination
-
- tests Rails::Generators::SerializerGenerator
- arguments %w(account name:string description:text business:references)
-
- def test_generates_a_serializer
- run_generator
- assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ActiveModel::Serializer/
- end
-
- def test_generates_a_namespaced_serializer
- run_generator ["admin/account"]
- assert_file "app/serializers/admin/account_serializer.rb", /class Admin::AccountSerializer < ActiveModel::Serializer/
- end
-
- def test_uses_application_serializer_if_one_exists
- Object.const_set(:ApplicationSerializer, Class.new)
- run_generator
- assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < ApplicationSerializer/
- ensure
- Object.send :remove_const, :ApplicationSerializer
- end
-
- # def test_uses_namespace_application_serializer_if_one_exists
- # Object.const_set(:SerializerNamespace, Module.new)
- # SerializerNamespace.const_set(:ApplicationSerializer, Class.new)
- # Rails::Generators.namespace = SerializerNamespace
- # run_generator
- # assert_file "app/serializers/serializer_namespace/account_serializer.rb",
- # /module SerializerNamespace\n class AccountSerializer < ApplicationSerializer/
- # ensure
- # Object.send :remove_const, :SerializerNamespace
- # Rails::Generators.namespace = nil
- # end
-
- def test_uses_given_parent
- Object.const_set(:ApplicationSerializer, Class.new)
- run_generator ["Account", "--parent=MySerializer"]
- assert_file "app/serializers/account_serializer.rb", /class AccountSerializer < MySerializer/
- ensure
- Object.send :remove_const, :ApplicationSerializer
- end
-
- def test_generates_attributes_and_associations
- run_generator
- assert_file "app/serializers/account_serializer.rb" do |serializer|
- assert_match(/^ attributes :id, :name, :description$/, serializer)
- assert_match(/^ has_one :business$/, serializer)
- end
- end
-
- def test_with_no_attributes_does_not_add_extra_space
- run_generator ["account"]
- assert_file "app/serializers/account_serializer.rb" do |content|
- assert_no_match /\n\nend/, content
- end
- end
-end
diff --git a/test/no_serialization_scope_test.rb b/test/no_serialization_scope_test.rb
deleted file mode 100644
index 31ba475f..00000000
--- a/test/no_serialization_scope_test.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-require "test_helper"
-
-class NoSerializationScopeTest < ActionController::TestCase
- class ScopeSerializer
- def initialize(object, options)
- @object, @options = object, options
- end
-
- def as_json(*)
- { scope: @options[:scope].as_json }
- end
- end
-
- class ScopeSerializable
- def active_model_serializer
- ScopeSerializer
- end
- end
-
- class NoSerializationScopeController < ActionController::Base
- serialization_scope nil
-
- def index
- render json: ScopeSerializable.new
- end
- end
-
- tests NoSerializationScopeController
-
- def test_disabled_serialization_scope
- get :index, format: :json
- assert_equal '{"scope":null}', @response.body
- end
-end
diff --git a/test/serialization_scope_name_test.rb b/test/serialization_scope_name_test.rb
deleted file mode 100644
index a5e164c4..00000000
--- a/test/serialization_scope_name_test.rb
+++ /dev/null
@@ -1,99 +0,0 @@
-require 'test_helper'
-require 'pathname'
-
-class DefaultScopeNameTest < ActionController::TestCase
- TestUser = Struct.new(:name, :admin)
-
- class UserSerializer < ActiveModel::Serializer
- attributes :admin?
- def admin?
- current_user.admin
- end
- end
-
- class UserTestController < ActionController::Base
- protect_from_forgery
-
- before_filter { request.format = :json }
-
- def current_user
- TestUser.new('Pete', false)
- end
-
- def render_new_user
- render json: TestUser.new('pete', false), serializer: UserSerializer
- end
- end
-
- tests UserTestController
-
- def test_default_scope_name
- get :render_new_user
- assert_equal '{"user":{"admin":false}}', @response.body
- end
-end
-
-class SerializationScopeNameTest < ActionController::TestCase
- TestUser = Struct.new(:name, :admin)
-
- class AdminUserSerializer < ActiveModel::Serializer
- attributes :admin?
- def admin?
- current_admin.admin
- end
- end
-
- class AdminUserTestController < ActionController::Base
- protect_from_forgery
-
- serialization_scope :current_admin
- before_filter { request.format = :json }
-
- def current_admin
- TestUser.new('Bob', true)
- end
-
- def render_new_user
- render json: TestUser.new('pete', false), serializer: AdminUserSerializer
- end
- end
-
- tests AdminUserTestController
-
- def test_override_scope_name_with_controller
- get :render_new_user
- assert_equal '{"admin_user":{"admin":true}}', @response.body
- end
-end
-
-class SerializationActionScopeOverrideTest < ActionController::TestCase
- TestUser = Struct.new(:name, :admin)
-
- class AdminUserSerializer < ActiveModel::Serializer
- attributes :admin?
- def admin?
- current_admin.admin
- end
- end
-
- class AdminUserTestController < ActionController::Base
- protect_from_forgery
- before_filter { request.format = :json }
-
- def current_admin
- TestUser.new('Bob', true)
- end
-
- def render_new_user
- render json: TestUser.new('pete', false), serializer: AdminUserSerializer, scope: current_admin, scope_name: :current_admin
- end
- end
-
- tests AdminUserTestController
-
- def test_override_scope_name_with_controller
- get :render_new_user
- assert_equal '{"admin_user":{"admin":true}}', @response.body
- end
-
-end
diff --git a/test/serialization_test.rb b/test/serialization_test.rb
deleted file mode 100644
index 6fe5075c..00000000
--- a/test/serialization_test.rb
+++ /dev/null
@@ -1,394 +0,0 @@
-require 'test_helper'
-require 'pathname'
-
-class RenderJsonTest < ActionController::TestCase
- class JsonRenderable
- def as_json(options={})
- hash = { a: :b, c: :d, e: :f }
- hash.except!(*options[:except]) if options[:except]
- hash
- end
-
- def to_json(options = {})
- super except: [:c, :e]
- end
- end
-
- class JsonSerializer
- def initialize(object, options={})
- @object, @options = object, options
- end
-
- def as_json(*)
- hash = { object: serializable_hash, scope: @options[:scope].as_json }
- hash.merge!(options: true) if @options[:options]
- hash.merge!(check_defaults: true) if @options[:check_defaults]
- hash
- end
-
- def serializable_hash
- @object.as_json
- end
- end
-
- class JsonSerializable
- def initialize(skip=false)
- @skip = skip
- end
-
- def active_model_serializer
- JsonSerializer unless @skip
- end
-
- def as_json(*)
- { serializable_object: true }
- end
- end
-
- class CustomSerializer
- def initialize(*)
- end
-
- def as_json(*)
- { hello: true }
- end
- end
-
- class AnotherCustomSerializer
- def initialize(*)
- end
-
- def as_json(*)
- { rails: 'rocks' }
- end
- end
-
- class DummyCustomSerializer < ActiveModel::Serializer
- attributes :id
- end
-
- class HypermediaSerializable
- def active_model_serializer
- HypermediaSerializer
- end
- end
-
- class HypermediaSerializer < ActiveModel::Serializer
- def as_json(*)
- { link: hypermedia_url }
- end
- end
-
- class CustomArraySerializer < ActiveModel::ArraySerializer
- self.root = "items"
- end
-
- class TestController < ActionController::Base
- protect_from_forgery
-
- serialization_scope :current_user
- attr_reader :current_user
-
- def self.controller_path
- 'test'
- end
-
- def render_json_nil
- render json: nil
- end
-
- def render_json_render_to_string
- render text: render_to_string(json: '[]')
- end
-
- def render_json_hello_world
- render json: ActiveSupport::JSON.encode(hello: 'world')
- end
-
- def render_json_hello_world_with_status
- render json: ActiveSupport::JSON.encode(hello: 'world'), status: 401
- end
-
- def render_json_hello_world_with_callback
- render json: ActiveSupport::JSON.encode(hello: 'world'), callback: 'alert'
- end
-
- def render_json_with_custom_content_type
- render json: ActiveSupport::JSON.encode(hello: 'world'), content_type: 'text/javascript'
- end
-
- def render_symbol_json
- render json: ActiveSupport::JSON.encode(hello: 'world')
- end
-
- def render_json_nil_with_custom_serializer
- render json: nil, serializer: DummyCustomSerializer
- end
-
-
- def render_json_with_extra_options
- render json: JsonRenderable.new, except: [:c, :e]
- end
-
- def render_json_without_options
- render json: JsonRenderable.new
- end
-
- def render_json_with_serializer
- @current_user = Struct.new(:as_json).new(current_user: true)
- render json: JsonSerializable.new
- end
-
- def render_json_with_serializer_and_implicit_root
- @current_user = Struct.new(:as_json).new(current_user: true)
- render json: [JsonSerializable.new]
- end
-
- def render_json_with_serializer_and_options
- @current_user = Struct.new(:as_json).new(current_user: true)
- render json: JsonSerializable.new, options: true
- end
-
- def render_json_with_serializer_and_scope_option
- @current_user = Struct.new(:as_json).new(current_user: true)
- scope = Struct.new(:as_json).new(current_user: false)
- render json: JsonSerializable.new, scope: scope
- end
-
- def render_json_with_serializer_api_but_without_serializer
- @current_user = Struct.new(:as_json).new(current_user: true)
- render json: JsonSerializable.new(true)
- end
-
- # To specify a custom serializer for an object, use :serializer.
- def render_json_with_custom_serializer
- render json: Object.new, serializer: CustomSerializer
- end
-
- # To specify a custom serializer for each item in the Array, use :each_serializer.
- def render_json_array_with_custom_serializer
- render json: [Object.new], each_serializer: CustomSerializer
- end
-
- def render_json_array_with_wrong_option
- render json: [Object.new], serializer: CustomSerializer
- end
-
- def render_json_with_links
- render json: HypermediaSerializable.new
- end
-
- def render_json_array_with_no_root
- render json: [], root: false
- end
-
- def render_json_empty_array
- render json: []
- end
-
- def render_json_array_with_custom_array_serializer
- render json: [], serializer: CustomArraySerializer
- end
-
-
- private
- def default_serializer_options
- defaults = {}
- defaults.merge!(check_defaults: true) if params[:check_defaults]
- defaults.merge!(root: :awesome) if params[:check_default_root]
- defaults.merge!(scope: :current_admin) if params[:check_default_scope]
- defaults.merge!(serializer: AnotherCustomSerializer) if params[:check_default_serializer]
- defaults.merge!(each_serializer: AnotherCustomSerializer) if params[:check_default_each_serializer]
- defaults
- end
- end
-
- tests TestController
-
- def setup
- # enable a logger so that (e.g.) the benchmarking stuff runs, so we can get
- # a more accurate simulation of what happens in "real life".
- super
- @controller.logger = Logger.new(nil)
-
- @request.host = "www.nextangle.com"
- end
-
- def test_render_json_nil
- get :render_json_nil
- assert_equal 'null', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_render_to_string
- get :render_json_render_to_string
- assert_equal '[]', @response.body
- end
-
- def test_render_json_nil_with_custom_serializer
- get :render_json_nil_with_custom_serializer
- assert_equal "{\"dummy_custom\":null}", @response.body
- end
-
- def test_render_json
- get :render_json_hello_world
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_with_status
- get :render_json_hello_world_with_status
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 401, @response.status
- end
-
- def test_render_json_with_callback
- get :render_json_hello_world_with_callback
- assert_equal 'alert({"hello":"world"})', @response.body
- # For JSONP, Rails 3 uses application/json, but Rails 4 uses text/javascript
- assert_match %r(application/json|text/javascript), @response.content_type.to_s
- end
-
- def test_render_json_with_custom_content_type
- get :render_json_with_custom_content_type
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'text/javascript', @response.content_type
- end
-
- def test_render_symbol_json
- get :render_symbol_json
- assert_equal '{"hello":"world"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_forwards_extra_options
- get :render_json_with_extra_options
- assert_equal '{"a":"b"}', @response.body
- assert_equal 'application/json', @response.content_type
- end
-
- def test_render_json_calls_to_json_from_object
- get :render_json_without_options
- assert_equal '{"a":"b"}', @response.body
- end
-
- def test_render_json_with_serializer
- get :render_json_with_serializer
- assert_match '"scope":{"current_user":true}', @response.body
- assert_match '"object":{"serializable_object":true}', @response.body
- end
-
- def test_render_json_with_serializer_checking_defaults
- get :render_json_with_serializer, check_defaults: true
- assert_match '"scope":{"current_user":true}', @response.body
- assert_match '"object":{"serializable_object":true}', @response.body
- assert_match '"check_defaults":true', @response.body
- end
-
- def test_render_json_with_serializer_checking_default_serailizer
- get :render_json_with_serializer, check_default_serializer: true
- assert_match '{"rails":"rocks"}', @response.body
- end
-
- def test_render_json_with_serializer_checking_default_scope
- get :render_json_with_serializer, check_default_scope: true
- assert_match '"scope":"current_admin"', @response.body
- end
-
- def test_render_json_with_serializer_and_implicit_root
- get :render_json_with_serializer_and_implicit_root
- assert_match '"test":[{"serializable_object":true}]', @response.body
- end
-
- def test_render_json_with_serializer_and_implicit_root_checking_default_each_serailizer
- get :render_json_with_serializer_and_implicit_root, check_default_each_serializer: true
- assert_match '"test":[{"rails":"rocks"}]', @response.body
- end
-
- def test_render_json_with_serializer_and_options
- get :render_json_with_serializer_and_options
- assert_match '"scope":{"current_user":true}', @response.body
- assert_match '"object":{"serializable_object":true}', @response.body
- assert_match '"options":true', @response.body
- end
-
- def test_render_json_with_serializer_and_scope_option
- get :render_json_with_serializer_and_scope_option
- assert_match '"scope":{"current_user":false}', @response.body
- end
-
- def test_render_json_with_serializer_and_scope_option_checking_default_scope
- get :render_json_with_serializer_and_scope_option, check_default_scope: true
- assert_match '"scope":{"current_user":false}', @response.body
- end
-
- def test_render_json_with_serializer_api_but_without_serializer
- get :render_json_with_serializer_api_but_without_serializer
- assert_match '{"serializable_object":true}', @response.body
- end
-
- def test_render_json_with_custom_serializer
- get :render_json_with_custom_serializer
- assert_match '{"hello":true}', @response.body
- end
-
- def test_render_json_with_custom_serializer_checking_default_serailizer
- get :render_json_with_custom_serializer, check_default_serializer: true
- assert_match '{"hello":true}', @response.body
- end
-
- def test_render_json_array_with_custom_serializer
- get :render_json_array_with_custom_serializer
- assert_match '{"test":[{"hello":true}]}', @response.body
- end
-
- def test_render_json_array_with_wrong_option
- assert_raise ArgumentError do
- get :render_json_array_with_wrong_option
- end
- end
-
- def test_render_json_array_with_custom_serializer_checking_default_each_serailizer
- get :render_json_array_with_custom_serializer, check_default_each_serializer: true
- assert_match '{"test":[{"hello":true}]}', @response.body
- end
-
- def test_render_json_with_links
- get :render_json_with_links
- assert_match '{"link":"http://www.nextangle.com/hypermedia"}', @response.body
- end
-
- def test_render_json_array_with_no_root
- get :render_json_array_with_no_root
- assert_equal '[]', @response.body
- end
-
- def test_render_json_array_with_no_root_checking_default_root
- get :render_json_array_with_no_root, check_default_root: true
- assert_equal '[]', @response.body
- end
-
- def test_render_json_empty_array
- get :render_json_empty_array
- assert_equal '{"test":[]}', @response.body
- end
-
- def test_render_json_empty_array_checking_default_root
- get :render_json_empty_array, check_default_root: true
- assert_equal '{"awesome":[]}', @response.body
- end
-
- def test_render_json_empty_array_with_array_serializer_root_false
- ActiveModel::ArraySerializer.root = false
- get :render_json_empty_array
- assert_equal '[]', @response.body
- ensure # teardown
- ActiveModel::ArraySerializer.root = nil
- end
-
- def test_render_json_array_with_custom_array_serializer
- get :render_json_array_with_custom_array_serializer
- assert_equal '{"items":[]}', @response.body
- end
-
-end
diff --git a/test/serializer_support_test.rb b/test/serializer_support_test.rb
deleted file mode 100644
index 03bd130f..00000000
--- a/test/serializer_support_test.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require "test_helper"
-
-class RandomModel
- include ActiveModel::SerializerSupport
-end
-
-class OtherRandomModel
- include ActiveModel::SerializerSupport
-end
-
-class OtherRandomModelSerializer
-end
-
-class RandomModelCollection
- include ActiveModel::ArraySerializerSupport
-end
-
-module ActiveRecord
- class Relation
- end
-end
-
-module Mongoid
- class Criteria
- end
-end
-
-class SerializerSupportTest < ActiveModel::TestCase
- test "it returns nil if no serializer exists" do
- assert_equal nil, RandomModel.new.active_model_serializer
- end
-
- test "it returns a deducted serializer if it exists exists" do
- assert_equal OtherRandomModelSerializer, OtherRandomModel.new.active_model_serializer
- end
-
- test "it returns ArraySerializer for a collection" do
- assert_equal ActiveModel::ArraySerializer, RandomModelCollection.new.active_model_serializer
- end
-
- test "it automatically includes array_serializer in active_record/relation" do
- ActiveSupport.run_load_hooks(:active_record)
- assert_equal ActiveModel::ArraySerializer, ActiveRecord::Relation.new.active_model_serializer
- end
-
- test "it automatically includes array_serializer in mongoid/criteria" do
- ActiveSupport.run_load_hooks(:mongoid)
- assert_equal ActiveModel::ArraySerializer, Mongoid::Criteria.new.active_model_serializer
- end
-end
-
diff --git a/test/serializer_test.rb b/test/serializer_test.rb
deleted file mode 100644
index 5da28d8a..00000000
--- a/test/serializer_test.rb
+++ /dev/null
@@ -1,1521 +0,0 @@
-require "test_helper"
-require "test_fakes"
-
-class SerializerTest < ActiveModel::TestCase
- def test_scope_works_correct
- serializer = ActiveModel::Serializer.new :foo, scope: :bar
- assert_equal serializer.scope, :bar
- end
-
- def test_attributes
- user = User.new
- user_serializer = DefaultUserSerializer.new(user, {})
-
- hash = user_serializer.as_json
-
- assert_equal({
- default_user: { first_name: "Jose", last_name: "Valim" }
- }, hash)
- end
-
- def test_attributes_method
- user = User.new
- user_serializer = UserSerializer.new(user, scope: {})
-
- hash = user_serializer.as_json
-
- assert_equal({
- user: { first_name: "Jose", last_name: "Valim", ok: true }
- }, hash)
- end
-
- def test_attributes_method_specifying_keys
- user = User.new
- user_serializer = UserAttributesWithKeySerializer.new(user, scope: {})
-
- hash = user_serializer.as_json
-
- assert_equal({
- user_attributes_with_key: { f_name: "Jose", l_name: "Valim", ok: true }
- }, hash)
- end
-
- def test_attributes_method_specifying_some_keys
- user = User.new
- user_serializer = UserAttributesWithSomeKeySerializer.new(user, scope: {})
-
- hash = user_serializer.as_json
-
- assert_equal({
- user_attributes_with_some_key: { first_name: "Jose", l_name: "Valim", ok: true }
- }, hash)
- end
-
- def test_attributes_method_with_unsymbolizable_key
- user = User.new
- user_serializer = UserAttributesWithUnsymbolizableKeySerializer.new(user, scope: {})
-
- hash = user_serializer.as_json
-
- assert_equal({
- user_attributes_with_unsymbolizable_key: { first_name: "Jose", :"last-name" => "Valim", ok: true }
- }, hash)
- end
-
- def test_attribute_method_with_name_as_serializer_prefix
- object = SomeObject.new("something")
- object_serializer = SomeSerializer.new(object, {})
-
- hash = object_serializer.as_json
-
- assert_equal({
- some: { some: "something" }
- }, hash)
- end
-
- def test_serializer_receives_scope
- user = User.new
- user_serializer = UserSerializer.new(user, scope: { scope: true })
-
- hash = user_serializer.as_json
-
- assert_equal({
- user: {
- first_name: "Jose",
- last_name: "Valim",
- ok: true,
- scope: true
- }
- }, hash)
- end
-
- def test_serializer_receives_url_options
- user = User.new
- user_serializer = UserSerializer.new(user, url_options: { host: "test.local" })
- assert_equal({ host: "test.local" }, user_serializer.url_options)
- end
-
- def test_serializer_returns_empty_hash_without_url_options
- user = User.new
- user_serializer = UserSerializer.new(user)
- assert_equal({}, user_serializer.url_options)
- end
-
- def test_pretty_accessors
- user = User.new
- user.superuser = true
- user_serializer = MyUserSerializer.new(user)
-
- hash = user_serializer.as_json
-
- assert_equal({
- my_user: {
- first_name: "Jose", last_name: "Valim", super_user: true
- }
- }, hash)
- end
-
- def test_has_many
- user = User.new
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
- post.comments = comments
-
- post_serializer = PostSerializer.new(post, scope: user)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]
- }
- }, post_serializer.as_json)
- end
-
- def test_conditionally_included_associations
- user = User.new
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
- post.comments = comments
-
- post_serializer = PostWithConditionalCommentsSerializer.new(post, scope: user)
-
- # comments enabled
- post.comments_disabled = false
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]
- }
- }, post_serializer.as_json)
-
- # comments disabled
- post.comments_disabled = true
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post"
- }
- }, post_serializer.as_json)
- end
-
- def test_conditionally_included_associations_and_attributes
- user = User.new
-
- post = Post.new(title: "New Post", body: "Body of new post", author: 'Sausage King', email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1"), Comment.new(title: "Comment2")]
- post.comments = comments
-
- post_serializer = PostWithMultipleConditionalsSerializer.new(post, scope: user)
-
- # comments enabled
- post.comments_disabled = false
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]
- }
- }, post_serializer.as_json)
-
- # comments disabled
- post.comments_disabled = true
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post"
- }
- }, post_serializer.as_json)
-
- # superuser - should see author
- user.superuser = true
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- author: "Sausage King"
- }
- }, post_serializer.as_json)
- end
-
- def test_has_one
- user = User.new
- blog = Blog.new
- blog.author = user
-
- json = BlogSerializer.new(blog, scope: user).as_json
- assert_equal({
- blog: {
- author: {
- first_name: "Jose",
- last_name: "Valim"
- }
- }
- }, json)
- end
-
- def test_overridden_associations
- author_serializer = Class.new(ActiveModel::Serializer) do
- attributes :first_name
- end
-
- blog_serializer = Class.new(ActiveModel::Serializer) do
- def person
- object.author
- end
-
- has_one :person, serializer: author_serializer
- end
-
- user = User.new
- blog = Blog.new
- blog.author = user
-
- json = blog_serializer.new(blog, scope: user).as_json
- assert_equal({
- person: {
- first_name: "Jose"
- }
- }, json)
- end
-
- def post_serializer
- Class.new(ActiveModel::Serializer) do
- attributes :title, :body
- has_many :comments, serializer: CommentSerializer
- has_one :author, serializer: DefaultUserSerializer
- end
- end
-
- def test_associations_with_nil_association
- user = User.new
- blog = Blog.new
-
- json = BlogSerializer.new(blog, scope: user).as_json
- assert_equal({
- blog: { author: nil }
- }, json)
-
- serializer = Class.new(BlogSerializer) do
- root :blog
- end
-
- json = serializer.new(blog, scope: user).as_json
- assert_equal({ blog: { author: nil } }, json)
- end
-
- def test_custom_root
- user = User.new
- blog = Blog.new
-
- serializer = Class.new(BlogSerializer) do
- root :my_blog
- end
-
- assert_equal({ my_blog: { author: nil } }, serializer.new(blog, scope: user).as_json)
- end
-
- def test_nil_root_object
- user = User.new
- blog = nil
-
- serializer = Class.new(BlogSerializer) do
- root false
- end
-
- assert_equal(nil, serializer.new(blog, scope: user).as_json)
- end
-
- def test_custom_root_with_nil_root_object
- user = User.new
- blog = nil
-
- serializer = Class.new(BlogSerializer) do
- root :my_blog
- end
-
- assert_equal({ my_blog: nil }, serializer.new(blog, scope: user).as_json)
- end
-
- def test_false_root
- user = User.new
- blog = Blog.new
-
- serializer = Class.new(BlogSerializer) do
- root false
- end
-
- another_serializer = Class.new(BlogSerializer) do
- self.root = false
- end
-
- assert_equal({ author: nil }, serializer.new(blog, scope: user).as_json)
- assert_equal({ author: nil }, another_serializer.new(blog, scope: user).as_json)
-
- # test inherited false root
- serializer = Class.new(serializer)
- assert_equal({ author: nil }, serializer.new(blog, scope: user).as_json)
- end
-
- def test_true_root
- blog = Blog.new
-
- assert_equal({
- blog_with_root: {
- author: nil,
- }
- }, BlogWithRootSerializer.new(blog).as_json)
- end
-
- def test_root_false_on_load_active_model_serializers
- begin
- ActiveSupport.on_load(:active_model_serializers) do
- self.root = false
- end
-
- blog = Blog.new
- serializer = BlogSerializer.new(blog)
-
- assert_equal({ author: nil }, serializer.as_json)
- ensure
- ActiveSupport.on_load(:active_model_serializers) do
- self.root = nil
- end
- end
- end
-
- def test_embed_ids
- serializer = post_serializer
-
- serializer.class_eval do
- root :post
- embed :ids
- end
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- serializer = serializer.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comment_ids: [1, 2],
- author_id: nil
- }
- }, serializer.as_json)
- end
-
- def test_embed_ids_include_true
- serializer_class = post_serializer
-
- serializer_class.class_eval do
- root :post
- embed :ids, include: true
- end
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- serializer = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comment_ids: [1, 2],
- author_id: nil
- },
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ],
- authors: []
- }, serializer.as_json)
-
- post.author = User.new(id: 1)
-
- serializer = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comment_ids: [1, 2],
- author_id: 1
- },
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ],
- authors: [{ first_name: "Jose", last_name: "Valim" }]
- }, serializer.as_json)
- end
-
- def test_methods_take_priority_over_associations
- post_serializer = Class.new(ActiveModel::Serializer) do
- attributes :title
- has_many :comments
- embed :ids
-
- def comments
- object.comments[0,1]
- end
- end
-
- post = Post.new(title: "My Post")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- post.class_eval do
- define_method :comment_ids, lambda {
- self.comments.map { |c| c.read_attribute_for_serialization(:id) }
- }
- end
- json = post_serializer.new(post).as_json
- assert_equal({
- title: "My Post",
- comment_ids: [1]
- }, json)
- end
-
- def test_methods_take_priority_over_associations_and_call_the_appropriate_id_method
- comment_serializer = Class.new(ActiveModel::Serializer) do
- def id
- "OMG"
- end
- end
-
- post_serializer = Class.new(ActiveModel::Serializer) do
- attributes :title
- has_many :comments, serializer: comment_serializer
- embed :ids
-
- def comments
- object.comments[0,1]
- end
- end
-
- post = Post.new(title: "My Post")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- post.class_eval do
- define_method :comment_ids, lambda {
- self.comments.map { |c| c.read_attribute_for_serialization(:id) }
- }
- end
- json = post_serializer.new(post).as_json
- assert_equal({
- title: "My Post",
- comment_ids: ["OMG"]
- }, json)
- end
-
- def test_embed_objects
- serializer = post_serializer
-
- serializer.class_eval do
- root :post
- embed :objects
- end
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- serializer = serializer.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- author: nil,
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ]
- }
- }, serializer.as_json)
- end
-
- def test_sets_can_be_serialized
- post1 = Post.new(title: "Post1", author: "Author1", id: 1)
- post2 = Post.new(title: "Post2", author: "Author2", id: 2)
-
- set = Set.new
- set << post1
- set << post2
-
- serializer = set.active_model_serializer.new set, each_serializer: CustomPostSerializer
-
- as_json = serializer.as_json
- assert_equal 2, as_json.size
- assert as_json.include?({ title: "Post1" })
- assert as_json.include?({ title: "Post2" })
- end
-
- def test_associations_with_as
- posts = [
- Post.new(title: 'First Post', body: 'text'),
- Post.new(title: 'Second Post', body: 'text')
- ]
- user = User.new
-
- custom_blog = CustomBlog.new
- custom_blog.public_posts = posts
- custom_blog.public_user = user
-
- serializer = CustomBlogSerializer.new(custom_blog, scope: { scope: true })
-
- assert_equal({
- custom_blog: {
- posts: [
- {title: 'First Post', body: 'text', comments: []},
- {title: 'Second Post', body: 'text', comments: []}
- ],
- user: {
- first_name: "Jose",
- last_name: "Valim", ok: true,
- scope: true
- }
- }
- }, serializer.as_json)
- end
-
- def test_implicity_detection_for_association_serializers
- implicit_serializer = Class.new(ActiveModel::Serializer) do
- root :custom_blog
- const_set(:UserSerializer, UserSerializer)
- const_set(:PostSerializer, PostSerializer)
-
- has_many :public_posts, key: :posts
- has_one :public_user, key: :user
- end
-
- posts = [
- Post.new(title: 'First Post', body: 'text', comments: []),
- Post.new(title: 'Second Post', body: 'text', comments: [])
- ]
- user = User.new
-
- custom_blog = CustomBlog.new
- custom_blog.public_posts = posts
- custom_blog.public_user = user
-
- serializer = implicit_serializer.new(custom_blog, scope: { scope: true })
-
- assert_equal({
- custom_blog: {
- posts: [
- {title: 'First Post', body: 'text', comments: []},
- {title: 'Second Post', body: 'text', comments: []}
- ],
- user: {
- first_name: "Jose",
- last_name: "Valim", ok: true,
- scope: true
- }
- }
- }, serializer.as_json)
- end
-
- def test_attribute_key
- serializer_class = Class.new(ActiveModel::Serializer) do
- root :user
-
- attribute :first_name, key: :firstName
- attribute :last_name, key: :lastName
- attribute :password
- end
-
- serializer = serializer_class.new(User.new)
-
- assert_equal({
- user: {
- firstName: "Jose",
- lastName: "Valim",
- password: "oh noes yugive my password"
- }
- }, serializer.as_json)
- end
-
- def setup_model
- Class.new do
- class << self
- def columns_hash
- { "name" => Struct.new(:type).new(:string), "age" => Struct.new(:type).new(:integer) }
- end
-
- def reflect_on_association(name)
- case name
- when :posts
- Struct.new(:macro, :name).new(:has_many, :posts)
- when :parent
- Struct.new(:macro, :name).new(:belongs_to, :parent)
- end
- end
- end
- end
- end
-
- def test_schema
- model = setup_model
-
- serializer = Class.new(ActiveModel::Serializer) do
- class << self; self; end.class_eval do
- define_method(:model_class) do model end
- end
-
- # Computed attributes (not real columns or associations).
- def can_edit; end
- def can_view; end
- def drafts; end
-
- attributes :name, :age, { can_edit: :boolean }, :can_view
- has_many :posts, serializer: Class.new
- has_many :drafts, serializer: Class.new
- has_one :parent, serializer: Class.new
- end
-
- assert_equal serializer.schema, {
- attributes: { name: :string, age: :integer, can_edit: :boolean, can_view: nil },
- associations: {
- posts: { has_many: :posts },
- drafts: nil,
- parent: { belongs_to: :parent }
- }
- }
- end
-
- def test_schema_with_as
- model = setup_model
-
- serializer = Class.new(ActiveModel::Serializer) do
- class << self; self; end.class_eval do
- define_method(:model_class) do model end
- end
-
- attributes :name, :age
- has_many :posts, key: :my_posts, serializer: Class.new
- has_one :parent, key: :my_parent, serializer: Class.new
- end
-
- assert_equal serializer.schema, {
- attributes: { name: :string, age: :integer },
- associations: {
- my_posts: { has_many: :posts },
- my_parent: { belongs_to: :parent }
- }
- }
- end
-
- def test_embed_id_for_has_one
- author_serializer = Class.new(ActiveModel::Serializer)
-
- serializer_class = Class.new(ActiveModel::Serializer) do
- embed :ids
- root :post
-
- attributes :title, :body
- has_one :author, serializer: author_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :author
- end
-
- author_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "It's a new post!")
- author = author_class.new(id: 5)
- post.author = author
-
- hash = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "It's a new post!",
- author_id: 5
- }
- }, hash.as_json)
- end
-
- def test_embed_id_for_has_one_overriding_associated_id
- author_serializer = Class.new(ActiveModel::Serializer) do
- def id
- "OMG"
- end
- end
-
- serializer_class = Class.new(ActiveModel::Serializer) do
- embed :ids
- root :post
-
- attributes :title, :body
- has_one :author, serializer: author_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :author
- end
-
- author_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "It's a new post!")
- author = author_class.new(id: 5)
- post.author = author
-
- hash = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "It's a new post!",
- author_id: "OMG"
- }
- }, hash.as_json)
- end
-
- def test_embed_objects_for_has_one
- author_serializer = Class.new(ActiveModel::Serializer) do
- attributes :id, :name
- end
-
- serializer_class = Class.new(ActiveModel::Serializer) do
- root :post
-
- attributes :title, :body
- has_one :author, serializer: author_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :author
- end
-
- author_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "It's a new post!")
- author = author_class.new(id: 5, name: "Tom Dale")
- post.author = author
-
- hash = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "It's a new post!",
- author: { id: 5, name: "Tom Dale" }
- }
- }, hash.as_json)
- end
-
- def test_root_provided_in_options
- author_serializer = Class.new(ActiveModel::Serializer) do
- attributes :id, :name
- end
-
- serializer_class = Class.new(ActiveModel::Serializer) do
- root :post
-
- attributes :title, :body
- has_one :author, serializer: author_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :author
- end
-
- author_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "It's a new post!")
- author = author_class.new(id: 5, name: "Tom Dale")
- post.author = author
-
- assert_equal({
- blog_post: {
- title: "New Post",
- body: "It's a new post!",
- author: { id: 5, name: "Tom Dale" }
- }
- }, serializer_class.new(post, root: :blog_post).as_json)
-
- assert_equal({
- title: "New Post",
- body: "It's a new post!",
- author: { id: 5, name: "Tom Dale" }
- }, serializer_class.new(post, root: false).as_json)
-
- assert_equal({
- blog_post: {
- title: "New Post",
- body: "It's a new post!",
- author: { id: 5, name: "Tom Dale" }
- }
- }, serializer_class.new(post).as_json(root: :blog_post))
-
- assert_equal({
- title: "New Post",
- body: "It's a new post!",
- author: { id: 5, name: "Tom Dale" }
- }, serializer_class.new(post).as_json(root: false))
- end
-
- def test_serializer_has_access_to_root_object
- hash_object = nil
-
- author_serializer = Class.new(ActiveModel::Serializer) do
- attributes :id, :name
-
- define_method :serializable_hash do
- hash_object = @options[:hash]
- super()
- end
- end
-
- serializer_class = Class.new(ActiveModel::Serializer) do
- root :post
-
- attributes :title, :body
- has_one :author, serializer: author_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :author
- end
-
- author_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "It's a new post!")
- author = author_class.new(id: 5, name: "Tom Dale")
- post.author = author
-
- expected = serializer_class.new(post).as_json
- assert_equal expected, hash_object
- end
-
- def test_embed_ids_include_true_with_root
- serializer_class = post_serializer
-
- serializer_class.class_eval do
- root :post
- embed :ids, include: true
- has_many :comments, key: :comment_ids, root: :comments
- has_one :author, serializer: DefaultUserSerializer, key: :author_id, root: :author
- end
-
- post = Post.new(title: "New Post", body: "Body of new post", email: "tenderlove@tenderlove.com")
- comments = [Comment.new(title: "Comment1", id: 1), Comment.new(title: "Comment2", id: 2)]
- post.comments = comments
-
- serializer = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comment_ids: [1, 2],
- author_id: nil
- },
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ],
- author: []
- }, serializer.as_json)
-
- post.author = User.new(id: 1)
-
- serializer = serializer_class.new(post)
-
- assert_equal({
- post: {
- title: "New Post",
- body: "Body of new post",
- comment_ids: [1, 2],
- author_id: 1
- },
- comments: [
- { title: "Comment1" },
- { title: "Comment2" }
- ],
- author: [{ first_name: "Jose", last_name: "Valim" }]
- }, serializer.as_json)
- end
-
- # the point of this test is to illustrate that deeply nested serializers
- # still side-load at the root.
- def test_embed_with_include_inserts_at_root
- tag_serializer = Class.new(ActiveModel::Serializer) do
- attributes :id, :name
- end
-
- comment_serializer = Class.new(ActiveModel::Serializer) do
- embed :ids, include: true
- attributes :id, :body
- has_many :tags, serializer: tag_serializer
- end
-
- post_serializer = Class.new(ActiveModel::Serializer) do
- embed :ids, include: true
- attributes :id, :title, :body
- has_many :comments, serializer: comment_serializer
- end
-
- post_class = Class.new(Model) do
- attr_accessor :comments
-
- define_method :active_model_serializer do
- post_serializer
- end
- end
-
- comment_class = Class.new(Model) do
- attr_accessor :tags
- end
-
- tag_class = Class.new(Model)
-
- post = post_class.new(title: "New Post", body: "NEW POST", id: 1)
- comment1 = comment_class.new(body: "EWOT", id: 1)
- comment2 = comment_class.new(body: "YARLY", id: 2)
- tag1 = tag_class.new(name: "lolcat", id: 1)
- tag2 = tag_class.new(name: "nyancat", id: 2)
- tag3 = tag_class.new(name: "violetcat", id: 3)
-
- post.comments = [comment1, comment2]
- comment1.tags = [tag1, tag3]
- comment2.tags = [tag1, tag2]
-
- actual = ActiveModel::ArraySerializer.new([post], root: :posts).as_json
- assert_equal({
- posts: [
- { title: "New Post", body: "NEW POST", id: 1, comment_ids: [1,2] }
- ],
-
- comments: [
- { body: "EWOT", id: 1, tag_ids: [1,3] },
- { body: "YARLY", id: 2, tag_ids: [1,2] }
- ],
-
- tags: [
- { name: "lolcat", id: 1 },
- { name: "violetcat", id: 3 },
- { name: "nyancat", id: 2 }
- ]
- }, actual)
- end
-
- def test_can_customize_attributes
- serializer = Class.new(ActiveModel::Serializer) do
- attributes :title, :body
-
- def title
- object.title.upcase
- end
- end
-
- klass = Class.new do
- def read_attribute_for_serialization(name)
- { title: "New post!", body: "First post body" }[name]
- end
-
- def title
- read_attribute_for_serialization(:title)
- end
-
- def body
- read_attribute_for_serialization(:body)
- end
- end
-
- object = klass.new
-
- actual = serializer.new(object, root: :post).as_json
-
- assert_equal({
- post: {
- title: "NEW POST!",
- body: "First post body"
- }
- }, actual)
- end
-
- def test_can_customize_attributes_with_read_attributes
- serializer = Class.new(ActiveModel::Serializer) do
- attributes :title, :body
-
- def read_attribute_for_serialization(name)
- { title: "New post!", body: "First post body" }[name]
- end
- end
-
- actual = serializer.new(Object.new, root: :post).as_json
-
- assert_equal({
- post: {
- title: "New post!",
- body: "First post body"
- }
- }, actual)
- end
-
- def test_active_support_on_load_hooks_fired
- loaded = nil
- ActiveSupport.on_load(:active_model_serializers) do
- loaded = self
- end
- assert_equal ActiveModel::Serializer, loaded
- end
-
- def tests_query_attributes_strip_question_mark
- todo = Class.new do
- def overdue?
- true
- end
-
- def read_attribute_for_serialization(name)
- send name
- end
- end
-
- serializer = Class.new(ActiveModel::Serializer) do
- attribute :overdue?
- end
-
- actual = serializer.new(todo.new).as_json
-
- assert_equal({
- overdue: true
- }, actual)
- end
-
- def tests_query_attributes_allow_key_option
- todo = Class.new do
- def overdue?
- true
- end
-
- def read_attribute_for_serialization(name)
- send name
- end
- end
-
- serializer = Class.new(ActiveModel::Serializer) do
- attribute :overdue?, key: :foo
- end
-
- actual = serializer.new(todo.new).as_json
-
- assert_equal({
- foo: true
- }, actual)
- end
-
- def tests_can_handle_polymorphism
- email_serializer = Class.new(ActiveModel::Serializer) do
- attributes :subject, :body
- end
-
- email_class = Class.new(Model) do
- def self.to_s
- "Email"
- end
-
- define_method :active_model_serializer do
- email_serializer
- end
- end
-
- attachment_serializer = Class.new(ActiveModel::Serializer) do
- attributes :name, :url
- has_one :attachable, polymorphic: true
- end
-
- email = email_class.new subject: 'foo', body: 'bar'
-
- attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
-
- actual = attachment_serializer.new(attachment, {}).as_json
-
- assert_equal({
- name: 'logo.png',
- url: 'http://example.com/logo.png',
- attachable: {
- type: :email,
- email: { subject: 'foo', body: 'bar' }
- }
- }, actual)
- end
-
- def test_can_handle_polymoprhic_ids
- email_serializer = Class.new(ActiveModel::Serializer) do
- attributes :subject, :body
- end
-
- email_class = Class.new(Model) do
- def self.to_s
- "Email"
- end
-
- define_method :active_model_serializer do
- email_serializer
- end
- end
-
- attachment_serializer = Class.new(ActiveModel::Serializer) do
- embed :ids
- attributes :name, :url
- has_one :attachable, polymorphic: true
- end
-
- email = email_class.new id: 1
-
- attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
-
- actual = attachment_serializer.new(attachment, {}).as_json
-
- assert_equal({
- name: 'logo.png',
- url: 'http://example.com/logo.png',
- attachable: {
- type: :email,
- id: 1
- }
- }, actual)
- end
-
- def test_polymorphic_associations_are_included_at_root
- email_serializer = Class.new(ActiveModel::Serializer) do
- attributes :subject, :body, :id
- end
-
- email_class = Class.new(Model) do
- def self.to_s
- "Email"
- end
-
- define_method :active_model_serializer do
- email_serializer
- end
- end
-
- attachment_serializer = Class.new(ActiveModel::Serializer) do
- root :attachment
- embed :ids, include: true
- attributes :name, :url
- has_one :attachable, polymorphic: true
- end
-
- email = email_class.new id: 1, subject: "Hello", body: "World"
-
- attachment = Attachment.new name: 'logo.png', url: 'http://example.com/logo.png', attachable: email
-
- actual = attachment_serializer.new(attachment, {}).as_json
-
- assert_equal({
- attachment: {
- name: 'logo.png',
- url: 'http://example.com/logo.png',
- attachable: {
- type: :email,
- id: 1
- }},
- emails: [{
- id: 1,
- subject: "Hello",
- body: "World"
- }]
- }, actual)
- end
-
- def test_multiple_polymorphic_associations
- email_serializer = Class.new(ActiveModel::Serializer) do
- attributes :subject, :body, :id
- end
-
- orange_serializer = Class.new(ActiveModel::Serializer) do
- embed :ids, include: true
-
- attributes :plu, :id
- has_one :readable, polymorphic: true
- end
-
- email_class = Class.new(Model) do
- def self.to_s
- "Email"
- end
-
- define_method :active_model_serializer do
- email_serializer
- end
- end
-
- orange_class = Class.new(Model) do
- def self.to_s
- "Orange"
- end
-
- def readable
- @attributes[:readable]
- end
-
- define_method :active_model_serializer do
- orange_serializer
- end
- end
-
- attachment_serializer = Class.new(ActiveModel::Serializer) do
- root :attachment
- embed :ids, include: true
-
- attributes :name, :url
-
- has_one :attachable, polymorphic: true
- has_one :readable, polymorphic: true
- has_one :edible, polymorphic: true
- end
-
- email = email_class.new id: 1, subject: "Hello", body: "World"
- orange = orange_class.new id: 1, plu: "3027", readable: email
-
- attachment = Attachment.new({
- name: 'logo.png',
- url: 'http://example.com/logo.png',
- attachable: email,
- readable: email,
- edible: orange
- })
-
- actual = attachment_serializer.new(attachment, {}).as_json
-
- assert_equal({
- emails: [{
- subject: "Hello",
- body: "World",
- id: 1
- }],
-
- oranges: [{
- plu: "3027",
- id: 1,
- readable: { type: :email, id: 1 }
- }],
-
- attachment: {
- name: 'logo.png',
- url: 'http://example.com/logo.png',
- attachable: { type: :email, id: 1 },
- readable: { type: :email, id: 1 },
- edible: { type: :orange, id: 1 }
- }
- }, actual)
- end
-
- def test_raises_an_error_when_a_child_serializer_includes_associations_when_the_source_doesnt
- attachment_serializer = Class.new(ActiveModel::Serializer) do
- attributes :name
- end
-
- fruit_serializer = Class.new(ActiveModel::Serializer) do
- embed :ids, include: true
- has_one :attachment, serializer: attachment_serializer
- attribute :color
- end
-
- banana_class = Class.new Model do
- def self.to_s
- 'banana'
- end
-
- def attachment
- @attributes[:attachment]
- end
-
- define_method :active_model_serializer do
- fruit_serializer
- end
- end
-
- strawberry_class = Class.new Model do
- def self.to_s
- 'strawberry'
- end
-
- def attachment
- @attributes[:attachment]
- end
-
- define_method :active_model_serializer do
- fruit_serializer
- end
- end
-
- smoothie = Class.new do
- attr_reader :base, :flavor
-
- def initialize(base, flavor)
- @base, @flavor = base, flavor
- end
- end
-
- smoothie_serializer = Class.new(ActiveModel::Serializer) do
- root false
- embed :ids, include: true
-
- has_one :base, polymorphic: true
- has_one :flavor, polymorphic: true
- end
-
- banana_attachment = Attachment.new({
- name: 'banana_blending.md',
- id: 3,
- })
-
- strawberry_attachment = Attachment.new({
- name: 'strawberry_cleaning.doc',
- id: 4
- })
-
- banana = banana_class.new color: "yellow", id: 1, attachment: banana_attachment
- strawberry = strawberry_class.new color: "red", id: 2, attachment: strawberry_attachment
-
- smoothie = smoothie_serializer.new(smoothie.new(banana, strawberry))
-
- assert_raise ActiveModel::Serializer::IncludeError do
- smoothie.as_json
- end
- end
-
- def tests_includes_does_not_include_nil_polymoprhic_associations
- post_serializer = Class.new(ActiveModel::Serializer) do
- root :post
- embed :ids, include: true
- has_one :author, polymorphic: true
- attributes :title
- end
-
- post = Post.new(title: 'Foo')
-
- actual = post_serializer.new(post).as_json
-
- assert_equal({
- post: {
- title: 'Foo',
- author: nil
- }
- }, actual)
- end
-
- def test_meta_key_serialization
- tag_serializer = Class.new(ActiveModel::Serializer) do
- attributes :name
- end
-
- tag_class = Class.new(Model) do
- def name
- @attributes[:name]
- end
-
- define_method :active_model_serializer do
- tag_serializer
- end
- end
-
- serializable_array = Class.new(Array)
-
- array = serializable_array.new
- array << tag_class.new(name: 'Rails')
- array << tag_class.new(name: 'Sinatra')
-
- actual = array.active_model_serializer.new(array, root: :tags, meta: {total: 10}).as_json
-
- assert_equal({
- meta: {
- total: 10,
- },
- tags: [
- { name: "Rails" },
- { name: "Sinatra" },
- ]
- }, actual)
-
- actual = array.active_model_serializer.new(array, root: :tags, meta: {total: 10}, meta_key: 'meta_object').as_json
-
- assert_equal({
- meta_object: {
- total: 10,
- },
- tags: [
- { name: "Rails" },
- { name: "Sinatra" },
- ]
- }, actual)
- end
-
- def test_inheritance_does_not_used_cached_attributes
- parent = Class.new(ActiveModel::Serializer) do
- attributes :title
- end
-
- child = Class.new(parent) do
- attributes :body
- end
-
- data_class = Class.new do
- attr_accessor :title, :body
- end
-
- item = data_class.new
- item.title = "title"
- item.body = "body"
-
- 2.times do
- assert_equal({title: "title"},
- parent.new(item).attributes)
- assert_equal({body: "body", title: "title"},
- child.new(item).attributes)
- end
-
- end
-
- def test_scope_name_method
- serializer = Class.new(ActiveModel::Serializer) do
- def has_permission?
- current_user.super_user?
- end
- end
-
- user = User.new
- user.superuser = true
- post = Post.new(title: 'Foo')
-
- a_serializer = serializer.new(post, scope: user, scope_name: :current_user)
- assert a_serializer.has_permission?
- end
-
- def test_only_option_filters_attributes_and_associations
- post = Post.new(title: "New Post", body: "Body of new post")
- comments = [Comment.new(title: "Comment1")]
- post.comments = comments
-
- post_serializer = PostSerializer.new(post, only: :title)
-
- assert_equal({
- post: {
- title: "New Post"
- }
- }, post_serializer.as_json)
- end
-
- def test_except_option_filters_attributes_and_associations
- post = Post.new(title: "New Post", body: "Body of new post")
- comments = [Comment.new(title: "Comment1")]
- post.comments = comments
-
- post_serializer = PostSerializer.new(post, except: [:body, :comments])
-
- assert_equal({
- post: {
- title: "New Post"
- }
- }, post_serializer.as_json)
- end
-
- def test_only_option_takes_precedence_over_custom_defined_include_methods
- user = User.new
-
- post = Post.new(title: "New Post", body: "Body of new post", author: "Sausage King")
- comments = [Comment.new(title: "Comment")]
- post.comments = comments
-
- post_serializer = PostWithMultipleConditionalsSerializer.new(post, scope: user, only: :title)
-
- # comments enabled
- post.comments_disabled = false
- # superuser - should see author
- user.superuser = true
-
- assert_equal({
- post: {
- title: "New Post"
- }
- }, post_serializer.as_json)
- end
-end
diff --git a/test/test_fakes.rb b/test/test_fakes.rb
deleted file mode 100644
index a0a244c1..00000000
--- a/test/test_fakes.rb
+++ /dev/null
@@ -1,202 +0,0 @@
-class Model
- def initialize(hash={})
- @attributes = hash
- end
-
- def read_attribute_for_serialization(name)
- @attributes[name]
- end
-
- def as_json(*)
- { model: "Model" }
- end
-end
-
-class ModelWithActiveModelSerializer < Model
- include ActiveModel::Serializers::JSON
- attr_accessor :attributes
- def read_attribute_for_serialization(name)
- @attributes[name]
- end
-end
-
-class User
- include ActiveModel::SerializerSupport
-
- attr_accessor :superuser
-
- def initialize(hash={})
- @attributes = hash.merge(first_name: "Jose", last_name: "Valim", password: "oh noes yugive my password")
- end
-
- def read_attribute_for_serialization(name)
- @attributes[name]
- end
-
- def super_user?
- @superuser
- end
-end
-
-class Post < Model
- def initialize(attributes)
- super(attributes)
- self.comments ||= []
- self.comments_disabled = false
- self.author = nil
- end
-
- attr_accessor :comments, :comments_disabled, :author
- def active_model_serializer; PostSerializer; end
-end
-
-class Comment < Model
- def active_model_serializer; CommentSerializer; end
-end
-
-class UserSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
-
- def serializable_hash
- attributes.merge(ok: true).merge(options[:scope])
- end
-end
-
-class UserAttributesWithKeySerializer < ActiveModel::Serializer
- attributes first_name: :f_name, last_name: :l_name
-
- def serializable_hash
- attributes.merge(ok: true).merge(options[:scope])
- end
-end
-
-class UserAttributesWithSomeKeySerializer < ActiveModel::Serializer
- attributes :first_name, last_name: :l_name
-
- def serializable_hash
- attributes.merge(ok: true).merge(options[:scope])
- end
-end
-
-class UserAttributesWithUnsymbolizableKeySerializer < ActiveModel::Serializer
- attributes :first_name, last_name: :"last-name"
-
- def serializable_hash
- attributes.merge(ok: true).merge(options[:scope])
- end
-end
-
-class DefaultUserSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
-end
-
-class MyUserSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
-
- def serializable_hash
- hash = attributes
- hash = hash.merge(super_user: true) if object.super_user?
- hash
- end
-end
-
-class CommentSerializer
- def initialize(comment, options={})
- @object = comment
- end
-
- attr_reader :object
-
- def serializable_hash
- { title: @object.read_attribute_for_serialization(:title) }
- end
-
- def as_json(options=nil)
- options ||= {}
- if options[:root] == false
- serializable_hash
- else
- { comment: serializable_hash }
- end
- end
-end
-
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
- has_many :comments, serializer: CommentSerializer
-end
-
-class PostWithConditionalCommentsSerializer < ActiveModel::Serializer
- root :post
- attributes :title, :body
- has_many :comments, serializer: CommentSerializer
-
- def include_associations!
- include! :comments unless object.comments_disabled
- end
-end
-
-class PostWithMultipleConditionalsSerializer < ActiveModel::Serializer
- root :post
- attributes :title, :body, :author
- has_many :comments, serializer: CommentSerializer
-
- def include_comments?
- !object.comments_disabled
- end
-
- def include_author?
- scope.super_user?
- end
-end
-
-class Blog < Model
- attr_accessor :author
-end
-
-class AuthorSerializer < ActiveModel::Serializer
- attributes :first_name, :last_name
-end
-
-class BlogSerializer < ActiveModel::Serializer
- has_one :author, serializer: AuthorSerializer
-end
-
-class BlogWithRootSerializer < BlogSerializer
- root true
-end
-
-class CustomPostSerializer < ActiveModel::Serializer
- attributes :title
-end
-
-class CustomBlog < Blog
- attr_accessor :public_posts, :public_user
-end
-
-class CustomBlogSerializer < ActiveModel::Serializer
- has_many :public_posts, key: :posts, serializer: PostSerializer
- has_one :public_user, key: :user, serializer: UserSerializer
-end
-
-class SomeSerializer < ActiveModel::Serializer
- attributes :some
-end
-
-class SomeObject < Struct.new(:some)
-end
-
-# Set up some classes for polymorphic testing
-class Attachment < Model
- def attachable
- @attributes[:attachable]
- end
-
- def readable
- @attributes[:readable]
- end
-
- def edible
- @attributes[:edible]
- end
-end
diff --git a/test/test_helper.rb b/test/test_helper.rb
deleted file mode 100644
index 889d7a60..00000000
--- a/test/test_helper.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-require "rubygems"
-require "bundler/setup"
-
-require 'simplecov'
-SimpleCov.start do
- add_group "lib", "lib"
- add_group "spec", "spec"
-end
-
-require 'coveralls'
-Coveralls.wear!
-
-require "pry"
-
-require "active_model_serializers"
-require "active_support/json"
-require "minitest/autorun"
-
-require 'rails'
-
-module TestHelper
- Routes = ActionDispatch::Routing::RouteSet.new
- Routes.draw do
- resource :hypermedia
- get ':controller(/:action(/:id))'
- get ':controller(/:action)'
- end
-
- ActionController::Base.send :include, Routes.url_helpers
- ActiveModel::Serializer.send :include, Routes.url_helpers
-end
-
-ActiveSupport::TestCase.class_eval do
- setup do
- @routes = ::TestHelper::Routes
- end
-end
-
-class Object
- undef_method :id if respond_to?(:id)
-end