active_model_serializers 0.8.4 → 0.9.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -45
  3. data/CONTRIBUTING.md +20 -0
  4. data/DESIGN.textile +4 -4
  5. data/{MIT-LICENSE.txt → MIT-LICENSE} +0 -0
  6. data/README.md +187 -113
  7. data/lib/action_controller/serialization.rb +30 -16
  8. data/lib/active_model/array_serializer.rb +36 -82
  9. data/lib/active_model/default_serializer.rb +22 -0
  10. data/lib/active_model/serializable.rb +25 -0
  11. data/lib/active_model/serializer.rb +126 -447
  12. data/lib/active_model/serializer/associations.rb +53 -211
  13. data/lib/active_model/serializer/config.rb +31 -0
  14. data/lib/active_model/serializer/generators/resource_override.rb +13 -0
  15. data/lib/{generators → active_model/serializer/generators}/serializer/USAGE +0 -0
  16. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +14 -0
  17. data/lib/active_model/serializer/generators/serializer/serializer_generator.rb +37 -0
  18. data/lib/active_model/serializer/generators/serializer/templates/controller.rb +93 -0
  19. data/lib/active_model/serializer/generators/serializer/templates/serializer.rb +8 -0
  20. data/lib/active_model/serializer/railtie.rb +10 -0
  21. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  22. data/lib/active_model/serializer_support.rb +5 -0
  23. data/lib/active_model_serializers.rb +7 -86
  24. data/test/coverage_setup.rb +15 -0
  25. data/test/fixtures/active_record.rb +92 -0
  26. data/test/fixtures/poro.rb +64 -0
  27. data/test/integration/action_controller/serialization_test.rb +234 -0
  28. data/test/integration/active_record/active_record_test.rb +77 -0
  29. data/test/integration/generators/resource_generator_test.rb +26 -0
  30. data/test/integration/generators/scaffold_controller_generator_test.rb +67 -0
  31. data/test/integration/generators/serializer_generator_test.rb +41 -0
  32. data/test/test_app.rb +11 -0
  33. data/test/test_helper.rb +7 -41
  34. data/test/tmp/app/serializers/account_serializer.rb +3 -0
  35. data/test/unit/active_model/array_serializer/meta_test.rb +53 -0
  36. data/test/unit/active_model/array_serializer/root_test.rb +102 -0
  37. data/test/unit/active_model/array_serializer/scope_test.rb +24 -0
  38. data/test/unit/active_model/array_serializer/serialization_test.rb +83 -0
  39. data/test/unit/active_model/default_serializer_test.rb +13 -0
  40. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +21 -0
  41. data/test/unit/active_model/serializer/associations_test.rb +19 -0
  42. data/test/unit/active_model/serializer/attributes_test.rb +41 -0
  43. data/test/unit/active_model/serializer/config_test.rb +86 -0
  44. data/test/unit/active_model/serializer/filter_test.rb +49 -0
  45. data/test/unit/active_model/serializer/has_many_test.rb +173 -0
  46. data/test/unit/active_model/serializer/has_one_test.rb +151 -0
  47. data/test/unit/active_model/serializer/meta_test.rb +39 -0
  48. data/test/unit/active_model/serializer/root_test.rb +117 -0
  49. data/test/unit/active_model/serializer/scope_test.rb +49 -0
  50. metadata +78 -74
  51. data/.gitignore +0 -18
  52. data/.travis.yml +0 -34
  53. data/Gemfile +0 -38
  54. data/Rakefile +0 -22
  55. data/active_model_serializers.gemspec +0 -24
  56. data/appveyor.yml +0 -27
  57. data/bench/perf.rb +0 -43
  58. data/cruft.md +0 -19
  59. data/lib/active_record/serializer_override.rb +0 -16
  60. data/lib/generators/resource_override.rb +0 -13
  61. data/lib/generators/serializer/serializer_generator.rb +0 -42
  62. data/lib/generators/serializer/templates/serializer.rb +0 -19
  63. data/test/array_serializer_test.rb +0 -75
  64. data/test/association_test.rb +0 -592
  65. data/test/caching_test.rb +0 -177
  66. data/test/generators_test.rb +0 -85
  67. data/test/no_serialization_scope_test.rb +0 -34
  68. data/test/serialization_scope_name_test.rb +0 -67
  69. data/test/serialization_test.rb +0 -396
  70. data/test/serializer_support_test.rb +0 -51
  71. data/test/serializer_test.rb +0 -1466
  72. data/test/test_fakes.rb +0 -218
data/.gitignore DELETED
@@ -1,18 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.swp
data/.travis.yml DELETED
@@ -1,34 +0,0 @@
1
- language: ruby
2
- sudo: false
3
- rvm:
4
- # - 1.8.7
5
- # - ree
6
- # - jruby-18mode
7
- # - 1.9.2
8
- # - 1.9.3
9
- - jruby-19mode
10
- - 2.0.0
11
- - 2.1
12
- - 2.2
13
- - rbx-2
14
- install: bundle install --path=vendor/bundle --retry=3 --jobs=3
15
- cache:
16
- directories:
17
- - vendor/bundle
18
- script:
19
- - bundle exec rake ci
20
- env:
21
- # - "RAILS_VERSION=3.0"
22
- # - "RAILS_VERSION=3.1"
23
- # - "RAILS_VERSION=3.2"
24
- - "RAILS_VERSION=4.0"
25
- - "RAILS_VERSION=4.1"
26
- - "RAILS_VERSION=4.2"
27
- # - "RAILS_VERSION=master"
28
- matrix:
29
- exclude:
30
- # - rvm: 1.8.7
31
- # - ree
32
- # - jruby-18mode
33
- # - rvm: 1.9.2
34
- fast_finish: true
data/Gemfile DELETED
@@ -1,38 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify gem dependencies in active_model_serializers.gemspec
4
- gemspec
5
-
6
- version = ENV['RAILS_VERSION'] || '4.0'
7
-
8
- if version == 'master'
9
- gem 'rack', github: 'rack/rack'
10
- gem 'arel', github: 'rails/arel'
11
- git 'https://github.com/rails/rails.git' do
12
- gem 'railties'
13
- gem 'activesupport'
14
- gem 'activemodel'
15
- gem 'actionpack'
16
- gem 'activerecord', group: :test
17
- # Rails 5
18
- gem 'actionview'
19
- end
20
- else
21
- gem_version = "~> #{version}.0"
22
- gem 'railties', gem_version
23
- gem 'activesupport', gem_version
24
- gem 'activemodel', gem_version
25
- gem 'actionpack', gem_version
26
- gem 'activerecord', gem_version, group: :test
27
- end
28
-
29
- # https://github.com/bundler/bundler/blob/89a8778c19269561926cea172acdcda241d26d23/lib/bundler/dependency.rb#L30-L54
30
- @windows_platforms = [:mswin, :mingw, :x64_mingw]
31
-
32
- # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
33
- gem 'tzinfo-data', platforms: (@windows_platforms + [:jruby])
34
-
35
- # JRuby versions before 9.x report their version as "1.9.x" or lower, so lock these to an older version of mime-types
36
- if defined?(JRUBY_VERSION) and Gem::ruby_version < Gem::Version.new("2.0.0")
37
- gem 'mime-types', '< 3'
38
- end
data/Rakefile DELETED
@@ -1,22 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require "rake/testtask"
4
-
5
- desc 'Run tests'
6
- Rake::TestTask.new(:test) do |t|
7
- t.libs << 'lib'
8
- t.libs << 'test'
9
- t.pattern = 'test/**/*_test.rb'
10
- t.ruby_opts = ['-r./test/test_helper.rb']
11
- t.verbose = true
12
- end
13
-
14
- desc 'Benchmark'
15
- task :bench do
16
- load 'bench/perf.rb'
17
- end
18
-
19
- task :default => :test
20
-
21
- desc 'CI test task'
22
- task :ci => :default
@@ -1,24 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- $:.unshift File.expand_path("../lib", __FILE__)
4
- require "active_model/serializers/version"
5
-
6
- Gem::Specification.new do |gem|
7
- gem.authors = ["José Valim", "Yehuda Katz"]
8
- gem.email = ["jose.valim@gmail.com", "wycats@gmail.com"]
9
- gem.description = %q{Making it easy to serialize models for client-side use}
10
- gem.summary = %q{Bringing consistency and object orientation to model serialization. Works great for client-side MVC frameworks!}
11
- gem.homepage = "https://github.com/rails-api/active_model_serializers"
12
-
13
- gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
- gem.files = `git ls-files`.split("\n")
15
- gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- gem.name = "active_model_serializers"
17
- gem.require_paths = ["lib"]
18
- gem.version = ActiveModel::Serializer::VERSION
19
-
20
- gem.add_dependency 'activemodel', '>= 3.0'
21
- gem.add_development_dependency "rails", ">= 3.0"
22
- gem.add_development_dependency "pry"
23
- gem.add_development_dependency "minitest"
24
- end
data/appveyor.yml DELETED
@@ -1,27 +0,0 @@
1
- version: '{build}'
2
-
3
- skip_tags: true
4
-
5
- environment:
6
- matrix:
7
- - ruby_version: "200"
8
- - ruby_version: "200-x64"
9
- - ruby_version: "21"
10
- - ruby_version: "21-x64"
11
-
12
- cache:
13
- - vendor/bundle
14
-
15
- install:
16
- - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
17
- - ruby --version
18
- - gem --version
19
- - gem install bundler
20
- - bundler --version
21
- - bundle platform
22
- - bundle install --path=vendor/bundle --retry=3 --jobs=3
23
-
24
- test_script:
25
- - bundle exec rake ci
26
-
27
- build: off
data/bench/perf.rb DELETED
@@ -1,43 +0,0 @@
1
- require "rubygems"
2
- require "bundler/setup"
3
- require "active_model_serializers"
4
- require "active_support/json"
5
- require "benchmark"
6
-
7
- class User < Struct.new(:id,:name,:age,:about)
8
- include ActiveModel::SerializerSupport
9
-
10
- def fast_hash
11
- h = {
12
- id: read_attribute_for_serialization(:id),
13
- name: read_attribute_for_serialization(:name),
14
- about: read_attribute_for_serialization(:about)
15
- }
16
- h[:age] = read_attribute_for_serialization(:age) if age > 18
17
- h
18
- end
19
- end
20
-
21
- class UserSerializer < ActiveModel::Serializer
22
- attributes :id, :name, :age, :about
23
-
24
- def include_age?
25
- object.age > 18
26
- end
27
- end
28
-
29
-
30
-
31
- u = User.new(1, "sam", 10, "about")
32
- s = UserSerializer.new(u)
33
-
34
- n = 100000
35
-
36
- Benchmark.bmbm {|x|
37
- x.report("init") { n.times { UserSerializer.new(u) } }
38
- x.report("fast_hash") { n.times { u.fast_hash } }
39
- x.report("attributes") { n.times { UserSerializer.new(u).attributes } }
40
- x.report("serializable_hash") { n.times { UserSerializer.new(u).serializable_hash } }
41
- }
42
-
43
-
data/cruft.md DELETED
@@ -1,19 +0,0 @@
1
- As of Ruby 1.9.3, it is impossible to dynamically generate a Symbol
2
- through interpolation without generating garbage. Theoretically, Ruby
3
- should be able to take care of this by building up the String in C and
4
- interning the C String.
5
-
6
- Because of this, we avoid generating dynamic Symbols at runtime. For
7
- example, instead of generating the instrumentation event dynamically, we
8
- have a constant with a Hash of events:
9
-
10
- ```ruby
11
- INSTRUMENT = {
12
- :serialize => :"serialize.serializer",
13
- :associations => :"associations.serializer"
14
- }
15
- ```
16
-
17
- If Ruby ever fixes this issue and avoids generating garbage with dynamic
18
- symbols, this code can be removed.
19
-
@@ -1,16 +0,0 @@
1
- # We do not recommend that you use AM::S in this way, but if you must, here
2
- # is a mixin that overrides ActiveRecord::Base#to_json and #as_json.
3
-
4
- module ActiveRecord
5
- module SerializerOverride
6
- def to_json options = {}
7
- active_model_serializer.new(self).to_json options
8
- end
9
-
10
- def as_json options={}
11
- active_model_serializer.new(self).as_json options
12
- end
13
- end
14
-
15
- Base.send(:include, SerializerOverride)
16
- end
@@ -1,13 +0,0 @@
1
- require "rails/generators"
2
- require "rails/generators/rails/resource/resource_generator"
3
-
4
- module Rails
5
- module Generators
6
- ResourceGenerator.class_eval do
7
- def add_serializer
8
- invoke "serializer"
9
- end
10
- end
11
- end
12
- end
13
-
@@ -1,42 +0,0 @@
1
- module Rails
2
- module Generators
3
- class SerializerGenerator < NamedBase
4
- source_root File.expand_path("../templates", __FILE__)
5
- check_class_collision :suffix => "Serializer"
6
-
7
- argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
8
-
9
- class_option :parent, :type => :string, :desc => "The parent class for the generated serializer"
10
-
11
- def create_serializer_file
12
- template 'serializer.rb', File.join('app/serializers', class_path, "#{file_name}_serializer.rb")
13
- end
14
-
15
- private
16
- def generate_id_method
17
- RUBY_VERSION =~ /1\.8/
18
- end
19
-
20
- def attributes_names
21
- [:id] + attributes.select { |attr| !attr.reference? }.map { |a| a.name.to_sym }
22
- end
23
-
24
- def association_names
25
- attributes.select { |attr| attr.reference? }.map { |a| a.name.to_sym }
26
- end
27
-
28
- def parent_class_name
29
- if options[:parent]
30
- options[:parent]
31
- # Only works on 3.2
32
- # elsif (n = Rails::Generators.namespace) && n.const_defined?(:ApplicationSerializer)
33
- # "ApplicationSerializer"
34
- elsif defined?(::ApplicationSerializer)
35
- "ApplicationSerializer"
36
- else
37
- "ActiveModel::Serializer"
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,19 +0,0 @@
1
- <% module_namespacing do -%>
2
- class <%= class_name %>Serializer < <%= parent_class_name %>
3
- attributes <%= attributes_names.map(&:inspect).join(", ") %>
4
- <% association_names.each do |attribute| -%>
5
- has_one :<%= attribute %>
6
- <% end -%>
7
- <% if generate_id_method %>
8
-
9
- # due to the difference between 1.8 and 1.9 with respect to #id and
10
- # #object_id, we recommend that if you wish to serialize id columns, you
11
- # do this. Feel free to remove this if you don't feel that it's appropriate.
12
- #
13
- # For more: https://github.com/rails-api/active_model_serializers/issues/127
14
- def id
15
- object.read_attribute_for_serialization(:id)
16
- end
17
- <% end -%>
18
- end
19
- <% end -%>
@@ -1,75 +0,0 @@
1
- require "test_helper"
2
- require "test_fakes"
3
-
4
- class ArraySerializerTest < ActiveModel::TestCase
5
-
6
- def test_array_items_do_not_have_root
7
- array = [
8
- BasicActiveModel.new(:name => "First model"),
9
- BasicActiveModel.new(:name => "Second model")
10
- ]
11
- expected = { "root" => [
12
- { :name => "First model" },
13
- { :name => "Second model" }
14
- ] }
15
-
16
- default_serializer = array.active_model_serializer.new(array, :root => "root")
17
- each_serializer = array.active_model_serializer.new(array, :root => "root", :each_serializer => BasicSerializer)
18
-
19
- default_json = default_serializer.as_json
20
- each_json = each_serializer.as_json
21
-
22
- assert_equal(expected, default_json)
23
- assert_equal(expected, each_json)
24
- end
25
-
26
- # serialize different typed objects
27
- def test_array_serializer
28
- model = Model.new
29
- user = User.new
30
- comments = Comment.new(:title => "Comment1", :id => 1)
31
-
32
- array = [model, user, comments]
33
- serializer = array.active_model_serializer.new(array, :scope => {:scope => true})
34
- assert_equal([
35
- { :model => "Model" },
36
- { :last_name => "Valim", :ok => true, :first_name => "Jose", :scope => true },
37
- { :title => "Comment1" }
38
- ], serializer.as_json)
39
- end
40
-
41
- def test_array_serializer_with_root
42
- comment1 = Comment.new(:title => "Comment1", :id => 1)
43
- comment2 = Comment.new(:title => "Comment2", :id => 2)
44
-
45
- array = [ comment1, comment2 ]
46
-
47
- serializer = array.active_model_serializer.new(array, :root => :comments)
48
-
49
- assert_equal({ :comments => [
50
- { :title => "Comment1" },
51
- { :title => "Comment2" }
52
- ]}, serializer.as_json)
53
- end
54
-
55
- def test_array_serializer_with_hash
56
- hash = {:value => "something"}
57
- array = [hash]
58
- serializer = array.active_model_serializer.new(array, :root => :items)
59
- assert_equal({ :items => [ hash.as_json ]}, serializer.as_json)
60
- end
61
-
62
- def test_array_serializer_with_specified_seriailizer
63
- post1 = Post.new(:title => "Post1", :author => "Author1", :id => 1)
64
- post2 = Post.new(:title => "Post2", :author => "Author2", :id => 2)
65
-
66
- array = [ post1, post2 ]
67
-
68
- serializer = array.active_model_serializer.new array, :each_serializer => CustomPostSerializer
69
-
70
- assert_equal([
71
- { :title => "Post1" },
72
- { :title => "Post2" }
73
- ], serializer.as_json)
74
- end
75
- end
@@ -1,592 +0,0 @@
1
- require "test_helper"
2
-
3
- class AssociationTest < ActiveModel::TestCase
4
- def def_serializer(&block)
5
- Class.new(ActiveModel::Serializer, &block)
6
- end
7
-
8
- class Model
9
- def initialize(hash={})
10
- @attributes = hash
11
- end
12
-
13
- def read_attribute_for_serialization(name)
14
- @attributes[name]
15
- end
16
-
17
- def as_json(*)
18
- { :model => "Model" }
19
- end
20
-
21
- def method_missing(meth, *args)
22
- if meth.to_s =~ /^(.*)=$/
23
- @attributes[$1.to_sym] = args[0]
24
- elsif @attributes.key?(meth)
25
- @attributes[meth]
26
- else
27
- super
28
- end
29
- end
30
- end
31
-
32
- def setup
33
- @hash = {}
34
- @root_hash = {}
35
-
36
- @post = Model.new(:title => "New Post", :body => "Body")
37
- @comment = Model.new(:id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT")
38
- @post.comments = [ @comment ]
39
- @post.comment = @comment
40
-
41
- @comment_serializer_class = def_serializer do
42
- attributes :id, :external_id, :body
43
- end
44
-
45
- @post_serializer_class = def_serializer do
46
- attributes :title, :body
47
- end
48
-
49
- @post_serializer = @post_serializer_class.new(@post, :hash => @root_hash)
50
- end
51
-
52
- def include!(key, options={})
53
- @post_serializer.include! key, {
54
- :embed => :ids,
55
- :include => true,
56
- :node => @hash,
57
- :serializer => @comment_serializer_class
58
- }.merge(options)
59
- end
60
-
61
- def include_bare!(key, options={})
62
- @post_serializer.include! key, {
63
- :node => @hash,
64
- :serializer => @comment_serializer_class
65
- }.merge(options)
66
- end
67
-
68
- class NoDefaults < AssociationTest
69
- def test_include_bang_has_many_associations
70
- include! :comments, :value => @post.comments
71
-
72
- assert_equal({
73
- :comment_ids => [ 1 ]
74
- }, @hash)
75
-
76
- assert_equal({
77
- :comments => [
78
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
79
- ]
80
- }, @root_hash)
81
- end
82
-
83
- def test_include_bang_with_embed_false
84
- include! :comments, :value => @post.comments, :embed => false
85
-
86
- assert_equal({}, @hash)
87
- assert_equal({}, @root_hash)
88
- end
89
-
90
- def test_include_bang_with_embed_ids_include_false
91
- include! :comments, :value => @post.comments, :embed => :ids, :include => false
92
-
93
- assert_equal({
94
- :comment_ids => [ 1 ]
95
- }, @hash)
96
-
97
- assert_equal({}, @root_hash)
98
- end
99
-
100
- def test_include_bang_has_one_associations
101
- include! :comment, :value => @post.comment
102
-
103
- assert_equal({
104
- :comment_id => 1
105
- }, @hash)
106
-
107
- assert_equal({
108
- :comments => [{ :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }]
109
- }, @root_hash)
110
- end
111
- end
112
-
113
- class DefaultsTest < AssociationTest
114
- def test_with_default_has_many
115
- @post_serializer_class.class_eval do
116
- has_many :comments
117
- end
118
-
119
- include! :comments
120
-
121
- assert_equal({
122
- :comment_ids => [ 1 ]
123
- }, @hash)
124
-
125
- assert_equal({
126
- :comments => [
127
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
128
- ]
129
- }, @root_hash)
130
- end
131
-
132
- def test_with_default_has_one
133
- @post_serializer_class.class_eval do
134
- has_one :comment
135
- end
136
-
137
- include! :comment
138
-
139
- assert_equal({
140
- :comment_id => 1
141
- }, @hash)
142
-
143
- assert_equal({
144
- :comments => [
145
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
146
- ]
147
- }, @root_hash)
148
- end
149
-
150
- def test_with_default_has_many_with_custom_key
151
- @post_serializer_class.class_eval do
152
- has_many :comments, :key => :custom_comments
153
- end
154
-
155
- include! :comments
156
-
157
- assert_equal({
158
- :custom_comments => [ 1 ]
159
- }, @hash)
160
-
161
- assert_equal({
162
- :comments => [
163
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
164
- ]
165
- }, @root_hash)
166
- end
167
-
168
- def test_with_default_has_one_with_custom_key
169
- @post_serializer_class.class_eval do
170
- has_one :comment, :key => :custom_comment_id
171
- end
172
-
173
- include! :comment
174
-
175
- assert_equal({
176
- :custom_comment_id => 1
177
- }, @hash)
178
-
179
- assert_equal({
180
- :comments => [
181
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
182
- ]
183
- }, @root_hash)
184
- end
185
-
186
- def test_with_default_has_many_with_custom_embed_key
187
- @post_serializer_class.class_eval do
188
- has_many :comments, :embed_key => :external_id
189
- end
190
-
191
- include! :comments
192
-
193
- assert_equal({
194
- :comment_ids => [ "COMM001" ]
195
- }, @hash)
196
-
197
- assert_equal({
198
- :comments => [
199
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
200
- ]
201
- }, @root_hash)
202
- end
203
-
204
- def test_with_default_has_one_with_custom_embed_key
205
- @post_serializer_class.class_eval do
206
- has_one :comment, :embed_key => :external_id
207
- end
208
-
209
- include! :comment
210
-
211
- assert_equal({
212
- :comment_id => "COMM001"
213
- }, @hash)
214
-
215
- assert_equal({
216
- :comments => [
217
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
218
- ]
219
- }, @root_hash)
220
- end
221
-
222
- def test_with_default_has_many_with_custom_key_and_custom_embed_key
223
- @post_serializer_class.class_eval do
224
- has_many :comments, :key => :custom_comments, :embed_key => :external_id
225
- end
226
-
227
- include! :comments
228
-
229
- assert_equal({
230
- :custom_comments => [ "COMM001" ]
231
- }, @hash)
232
-
233
- assert_equal({
234
- :comments => [
235
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
236
- ]
237
- }, @root_hash)
238
- end
239
-
240
- def test_with_default_has_one_with_custom_key_and_custom_embed_key
241
- @post_serializer_class.class_eval do
242
- has_one :comment, :key => :custom_comment, :embed_key => :external_id
243
- end
244
-
245
- include! :comment
246
-
247
- assert_equal({
248
- :custom_comment => "COMM001"
249
- }, @hash)
250
-
251
- assert_equal({
252
- :comments => [
253
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
254
- ]
255
- }, @root_hash)
256
- end
257
-
258
- def test_embed_objects_for_has_many_associations
259
- @post_serializer_class.class_eval do
260
- has_many :comments, :embed => :objects
261
- end
262
-
263
- include_bare! :comments
264
-
265
- assert_equal({
266
- :comments => [
267
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
268
- ]
269
- }, @hash)
270
-
271
- assert_equal({}, @root_hash)
272
- end
273
-
274
- def test_embed_ids_for_has_many_associations
275
- @post_serializer_class.class_eval do
276
- has_many :comments, :embed => :ids
277
- end
278
-
279
- include_bare! :comments
280
-
281
- assert_equal({
282
- :comment_ids => [ 1 ]
283
- }, @hash)
284
-
285
- assert_equal({}, @root_hash)
286
- end
287
-
288
- def test_embed_false_for_has_many_associations
289
- @post_serializer_class.class_eval do
290
- has_many :comments, :embed => false
291
- end
292
-
293
- include_bare! :comments
294
-
295
- assert_equal({}, @hash)
296
- assert_equal({}, @root_hash)
297
- end
298
-
299
- def test_embed_ids_include_true_for_has_many_associations
300
- @post_serializer_class.class_eval do
301
- has_many :comments, :embed => :ids, :include => true
302
- end
303
-
304
- include_bare! :comments
305
-
306
- assert_equal({
307
- :comment_ids => [ 1 ]
308
- }, @hash)
309
-
310
- assert_equal({
311
- :comments => [
312
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
313
- ]
314
- }, @root_hash)
315
- end
316
-
317
- def test_embed_ids_for_has_one_associations
318
- @post_serializer_class.class_eval do
319
- has_one :comment, :embed => :ids
320
- end
321
-
322
- include_bare! :comment
323
-
324
- assert_equal({
325
- :comment_id => 1
326
- }, @hash)
327
-
328
- assert_equal({}, @root_hash)
329
- end
330
-
331
- def test_embed_false_for_has_one_associations
332
- @post_serializer_class.class_eval do
333
- has_one :comment, :embed => false
334
- end
335
-
336
- include_bare! :comment
337
-
338
- assert_equal({}, @hash)
339
- assert_equal({}, @root_hash)
340
- end
341
-
342
- def test_embed_ids_include_true_for_has_one_associations
343
- @post_serializer_class.class_eval do
344
- has_one :comment, :embed => :ids, :include => true
345
- end
346
-
347
- include_bare! :comment
348
-
349
- assert_equal({
350
- :comment_id => 1
351
- }, @hash)
352
-
353
- assert_equal({
354
- :comments => [
355
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
356
- ]
357
- }, @root_hash)
358
- end
359
-
360
- def test_embed_ids_include_true_does_not_serialize_multiple_times
361
- @post.recent_comment = @comment
362
-
363
- @post_serializer_class.class_eval do
364
- has_one :comment, :embed => :ids, :include => true
365
- has_one :recent_comment, :embed => :ids, :include => true, :root => :comments
366
- end
367
-
368
- # Count how often the @comment record is serialized.
369
- serialized_times = 0
370
- @comment.class_eval do
371
- define_method :read_attribute_for_serialization, lambda { |name|
372
- serialized_times += 1 if name == :body
373
- super(name)
374
- }
375
- end
376
-
377
- include_bare! :comment
378
- include_bare! :recent_comment
379
-
380
- assert_equal 1, serialized_times
381
- end
382
-
383
- def test_include_with_read_association_id_for_serialization_hook
384
- @post_serializer_class.class_eval do
385
- has_one :comment, :embed => :ids, :include => true
386
- end
387
-
388
- association_name = nil
389
- @post.class_eval do
390
- define_method :read_attribute_for_serialization, lambda { |name|
391
- association_name = name
392
- send(name)
393
- }
394
- define_method :comment_id, lambda {
395
- @attributes[:comment].id
396
- }
397
- end
398
-
399
- include_bare! :comment
400
-
401
- assert_equal({
402
- :comment_id => 1
403
- }, @hash)
404
- end
405
-
406
- def test_include_with_read_association_ids_for_serialization_hook
407
- @post_serializer_class.class_eval do
408
- has_many :comments, :embed => :ids, :include => false
409
- end
410
-
411
- association_name = nil
412
- @post.class_eval do
413
- define_method :read_attribute_for_serialization, lambda { |name|
414
- association_name = name
415
- send(name)
416
- }
417
- define_method :comment_ids, lambda {
418
- @attributes[:comments].map(&:id)
419
- }
420
- end
421
-
422
- include_bare! :comments
423
-
424
- assert_equal({
425
- :comment_ids => [1]
426
- }, @hash)
427
- end
428
- end
429
-
430
- class RecursiveTest < AssociationTest
431
- class BarSerializer < ActiveModel::Serializer; end
432
-
433
- class FooSerializer < ActiveModel::Serializer
434
- root :foos
435
- attributes :id
436
- has_many :bars, :serializer => BarSerializer, :root => :bars, :embed => :ids, :include => true
437
- end
438
-
439
- class BarSerializer < ActiveModel::Serializer
440
- root :bars
441
- attributes :id
442
- has_many :foos, :serializer => FooSerializer, :root => :foos, :embed => :ids, :include => true
443
- end
444
-
445
- class Foo < Model
446
- def active_model_serializer; FooSerializer; end
447
- end
448
-
449
- class Bar < Model
450
- def active_model_serializer; BarSerializer; end
451
- end
452
-
453
- def setup
454
- super
455
-
456
- foo = Foo.new(:id => 1)
457
- bar = Bar.new(:id => 2)
458
-
459
- foo.bars = [ bar ]
460
- bar.foos = [ foo ]
461
-
462
- collection = [ foo ]
463
-
464
- @serializer = collection.active_model_serializer.new(collection, :root => :foos)
465
- end
466
-
467
- def test_mutual_relation_result
468
- assert_equal({
469
- :foos => [{
470
- :bar_ids => [ 2 ],
471
- :id => 1
472
- }],
473
- :bars => [{
474
- :foo_ids => [ 1 ],
475
- :id => 2
476
- }]
477
- }, @serializer.as_json)
478
- end
479
-
480
- def test_mutual_relation_does_not_raise_error
481
- assert_nothing_raised SystemStackError, 'stack level too deep' do
482
- @serializer.as_json
483
- end
484
- end
485
- end
486
-
487
- class InclusionTest < AssociationTest
488
- def setup
489
- super
490
-
491
- comment_serializer_class = @comment_serializer_class
492
-
493
- @post_serializer_class.class_eval do
494
- root :post
495
- embed :ids, :include => true
496
- has_many :comments, :serializer => comment_serializer_class
497
- end
498
- end
499
-
500
- def test_when_it_is_included
501
- post_serializer = @post_serializer_class.new(
502
- @post, :include => [:comments]
503
- )
504
-
505
- json = post_serializer.as_json
506
-
507
- assert_equal({
508
- :post => {
509
- :title => "New Post",
510
- :body => "Body",
511
- :comment_ids => [ 1 ]
512
- },
513
- :comments => [
514
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
515
- ]
516
- }, json)
517
- end
518
-
519
- def test_when_it_is_not_included
520
- post_serializer = @post_serializer_class.new(
521
- @post, :include => []
522
- )
523
-
524
- json = post_serializer.as_json
525
-
526
- assert_equal({
527
- :post => {
528
- :title => "New Post",
529
- :body => "Body",
530
- :comment_ids => [ 1 ]
531
- }
532
- }, json)
533
- end
534
-
535
- def test_when_it_is_excluded
536
- post_serializer = @post_serializer_class.new(
537
- @post, :exclude => [:comments]
538
- )
539
-
540
- json = post_serializer.as_json
541
-
542
- assert_equal({
543
- :post => {
544
- :title => "New Post",
545
- :body => "Body",
546
- :comment_ids => [ 1 ]
547
- }
548
- }, json)
549
- end
550
-
551
- def test_when_it_is_not_excluded
552
- post_serializer = @post_serializer_class.new(
553
- @post, :exclude => []
554
- )
555
-
556
- json = post_serializer.as_json
557
-
558
- assert_equal({
559
- :post => {
560
- :title => "New Post",
561
- :body => "Body",
562
- :comment_ids => [ 1 ]
563
- },
564
- :comments => [
565
- { :id => 1, :external_id => "COMM001", :body => "ZOMG A COMMENT" }
566
- ]
567
- }, json)
568
- end
569
- end
570
-
571
- class StringSerializerOption < AssociationTest
572
- class StringSerializer < ActiveModel::Serializer
573
- attributes :id, :body
574
- end
575
-
576
- def test_specifying_serializer_class_as_string
577
- @post_serializer_class.class_eval do
578
- has_many :comments, :embed => :objects
579
- end
580
-
581
- include_bare! :comments, :serializer => "AssociationTest::StringSerializerOption::StringSerializer"
582
-
583
- assert_equal({
584
- :comments => [
585
- { :id => 1, :body => "ZOMG A COMMENT" }
586
- ]
587
- }, @hash)
588
-
589
- assert_equal({}, @root_hash)
590
- end
591
- end
592
- end