aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG.md2
-rw-r--r--railties/guides/source/serializers.textile563
-rw-r--r--railties/lib/rails/generators.rb4
-rw-r--r--railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb1
-rw-r--r--railties/lib/rails/generators/rails/serializer/USAGE9
-rw-r--r--railties/lib/rails/generators/rails/serializer/serializer_generator.rb39
-rw-r--r--railties/lib/rails/generators/rails/serializer/templates/serializer.rb9
-rw-r--r--railties/lib/rails/generators/test_unit/serializer/serializer_generator.rb13
-rw-r--r--railties/lib/rails/generators/test_unit/serializer/templates/unit_test.rb9
-rw-r--r--railties/test/generators/scaffold_generator_test.rb9
-rw-r--r--railties/test/generators/serializer_generator_test.rb63
11 files changed, 1 insertions, 720 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index 1b89bfa6f9..6b0be4c096 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -7,8 +7,6 @@
Example:
config.railties_order = [Blog::Engine, :main_app, :all]
-* Add a serializer generator and add a hook for it in the scaffold generators *José Valim*
-
* Scaffold returns 204 No Content for API requests without content. This makes scaffold work with jQuery out of the box. *José Valim*
* Update Rails::Rack::Logger middleware to apply any tags set in config.log_tags to the newly ActiveSupport::TaggedLogging Rails.logger. This makes it easy to tag log lines with debug information like subdomain and request id -- both very helpful in debugging multi-user production applications *DHH*
diff --git a/railties/guides/source/serializers.textile b/railties/guides/source/serializers.textile
deleted file mode 100644
index efc7cbf248..0000000000
--- a/railties/guides/source/serializers.textile
+++ /dev/null
@@ -1,563 +0,0 @@
-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.
-
-endprologue.
-
-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.
-
-<ruby>
-class PostSerializer
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- def as_json
- { post: { title: @post.name, body: @post.body } }
- end
-end
-</ruby>
-
-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.
-
-<ruby>
-class PostsController < ApplicationController
- def show
- @post = Post.find(params[:id])
- render json: @post
- end
-end
-</ruby>
-
-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.
-
-<ruby>
-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
-</ruby>
-
-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.
-
-<ruby>
-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
-</ruby>
-
-h4. Testing
-
-One benefit of encapsulating our objects this way is that it becomes extremely straight-forward to test the serialization
-logic in isolation.
-
-<ruby>
-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
-</ruby>
-
-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:
-
-<ruby>
-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
-</ruby>
-
-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.
-
-<ruby>
-class PostSerializer < ActiveModel::Serializer
- attributes :title, :body
-
- def initialize(post, scope)
- @post, @scope = post, scope
- end
-
- 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
-</ruby>
-
-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 methood 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!
-
-<ruby>
-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
-</ruby>
-
-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.
-
-<ruby>
-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
-</ruby>
-
-The default +serializable_hash+ method will include the comments as embedded objects inside the post.
-
-<javascript>
-{
- post: {
- title: "Hello Blog!",
- body: "This is my first post. Isn't it fabulous!",
- comments: [
- {
- title: "Awesome",
- body: "Your first post is great"
- }
- ]
- }
-}
-</javascript>
-
-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.
-
-<ruby>
-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
-</ruby>
-
-If we define the above comment serializer, the outputted JSON will change to:
-
-<javascript>
-{
- post: {
- title: "Hello Blog!",
- body: "This is my first post. Isn't it fabulous!",
- comments: [{ title: "Awesome" }]
- }
-}
-</javascript>
-
-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.
-
-<ruby>
-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
-</ruby>
-
-+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.
-
-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:
-
-<plain>
-{
- 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!"
- }
- ]
-}
-</plain>
-
-We could achieve this with a custom +as_json+ method. We will also need to define a serializer for comments.
-
-<ruby>
-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
-</ruby>
-
-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.
-
-<ruby>
-class PostSerializer < ActiveModel::Serializer
- class CommentSerializer < ActiveModel::Serializer
- attributes :id, :title
- end
-
- # same as before
- # ...
-end
-</ruby>
-
-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.
-
-<ruby>
-class PostsController < ApplicationController
- serialization_scope :current_app
-end
-</ruby>
-
-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:
-
-<ruby>
-user = get_user # some logic to get the user in question
-PostSerializer.new(post, user).to_json # reliably generate JSON output
-</ruby>
-
-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:
-
-<ruby>
-user = User.new # create a new anonymous user
-PostSerializer.new(post, user).to_json
-</ruby>
-
-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:
-
-<plain>
-{
- posts: [
- {
- title: "FIRST POST!",
- body: "It's my first pooooost"
- },
- { title: "Second post!",
- body: "Zomg I made it to my second post"
- }
- ]
-}
-</plain>
-
-If you want to change the behavior of serialized Arrays, you need to create
-a custom Array serializer.
-
-<ruby>
-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
-</ruby>
-
-When generating embedded associations using the +associations+ helper inside a
-regular serializer, it will create a new <code>ArraySerializer</code> 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/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index f1ca9080ff..27f8d13ce8 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -33,8 +33,7 @@ module Rails
:stylesheets => '-y',
:stylesheet_engine => '-se',
:template_engine => '-e',
- :test_framework => '-t',
- :serializer => '-z'
+ :test_framework => '-t'
},
:test_unit => {
@@ -59,7 +58,6 @@ module Rails
:performance_tool => nil,
:resource_controller => :controller,
:scaffold_controller => :scaffold_controller,
- :serializer => false,
:stylesheets => true,
:stylesheet_engine => :css,
:test_framework => false,
diff --git a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
index 7353a67c83..03a61a035e 100644
--- a/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
+++ b/railties/lib/rails/generators/rails/scaffold/scaffold_generator.rb
@@ -10,7 +10,6 @@ module Rails
class_option :stylesheet_engine, :desc => "Engine for Stylesheets"
hook_for :scaffold_controller, :required => true
- hook_for :serializer
hook_for :assets do |assets|
invoke assets, [controller_name]
diff --git a/railties/lib/rails/generators/rails/serializer/USAGE b/railties/lib/rails/generators/rails/serializer/USAGE
deleted file mode 100644
index a49f7ea1fb..0000000000
--- a/railties/lib/rails/generators/rails/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/railties/lib/rails/generators/rails/serializer/serializer_generator.rb b/railties/lib/rails/generators/rails/serializer/serializer_generator.rb
deleted file mode 100644
index 2118906227..0000000000
--- a/railties/lib/rails/generators/rails/serializer/serializer_generator.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-module Rails
- module Generators
- class SerializerGenerator < NamedBase
- 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
-
- hook_for :test_framework
-
- private
-
- def attributes_names
- 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 (n = Rails::Generators.namespace) && n.const_defined?(:ApplicationSerializer)
- "ApplicationSerializer"
- elsif Object.const_defined?(:ApplicationSerializer)
- "ApplicationSerializer"
- else
- "ActiveModel::Serializer"
- end
- end
- end
- end
-end
diff --git a/railties/lib/rails/generators/rails/serializer/templates/serializer.rb b/railties/lib/rails/generators/rails/serializer/templates/serializer.rb
deleted file mode 100644
index 30c058c7e9..0000000000
--- a/railties/lib/rails/generators/rails/serializer/templates/serializer.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-<% module_namespacing do -%>
-class <%= class_name %>Serializer < <%= parent_class_name %>
-<% if attributes.any? -%> attributes <%= attributes_names.map(&:inspect).join(", ") %>
-<% end -%>
-<% association_names.each do |attribute| -%>
- has_one :<%= attribute %>
-<% end -%>
-end
-<% end -%> \ No newline at end of file
diff --git a/railties/lib/rails/generators/test_unit/serializer/serializer_generator.rb b/railties/lib/rails/generators/test_unit/serializer/serializer_generator.rb
deleted file mode 100644
index 533c032c3b..0000000000
--- a/railties/lib/rails/generators/test_unit/serializer/serializer_generator.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-require 'rails/generators/test_unit'
-
-module TestUnit
- module Generators
- class SerializerGenerator < Base
- check_class_collision :suffix => "SerializerTest"
-
- def create_test_files
- template 'unit_test.rb', File.join('test/unit', class_path, "#{file_name}_serializer_test.rb")
- end
- end
- end
-end
diff --git a/railties/lib/rails/generators/test_unit/serializer/templates/unit_test.rb b/railties/lib/rails/generators/test_unit/serializer/templates/unit_test.rb
deleted file mode 100644
index 0b1bbdcaa5..0000000000
--- a/railties/lib/rails/generators/test_unit/serializer/templates/unit_test.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-require 'test_helper'
-
-<% module_namespacing do -%>
-class <%= class_name %>SerializerTest < ActiveSupport::TestCase
- # test "the truth" do
- # assert true
- # end
-end
-<% end -%>
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 2e8b03fbef..2db8090621 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -264,15 +264,6 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
assert_file "app/assets/stylesheets/posts.css"
end
- def test_scaffold_also_generators_serializer
- run_generator [ "posts", "name:string", "author:references", "--serializer" ]
- assert_file "app/serializers/post_serializer.rb" do |serializer|
- assert_match /class PostSerializer < ActiveModel::Serializer/, serializer
- assert_match /^ attributes :name$/, serializer
- assert_match /^ has_one :author$/, serializer
- end
- end
-
def test_scaffold_generator_outputs_error_message_on_missing_attribute_type
run_generator ["post", "title", "body:text", "author"]
diff --git a/railties/test/generators/serializer_generator_test.rb b/railties/test/generators/serializer_generator_test.rb
deleted file mode 100644
index 2afaa65693..0000000000
--- a/railties/test/generators/serializer_generator_test.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-require 'generators/generators_test_helper'
-require 'rails/generators/rails/serializer/serializer_generator'
-
-class SerializerGeneratorTest < Rails::Generators::TestCase
- include GeneratorsTestHelper
- 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 :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", /class AccountSerializer < ActiveModel::Serializer\nend/
- end
-
- def test_invokes_default_test_framework
- run_generator
- assert_file "test/unit/account_serializer_test.rb", /class AccountSerializerTest < ActiveSupport::TestCase/
- end
-end