active_model_serializers 0.8.3 → 0.9.1

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -5
  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 +395 -95
  7. data/lib/action_controller/serialization.rb +50 -12
  8. data/lib/action_controller/serialization_test_case.rb +79 -0
  9. data/lib/active_model/array_serializer.rb +46 -78
  10. data/lib/active_model/default_serializer.rb +32 -0
  11. data/lib/active_model/serializable/utils.rb +16 -0
  12. data/lib/active_model/serializable.rb +62 -0
  13. data/lib/active_model/serializer/association/has_many.rb +39 -0
  14. data/lib/active_model/serializer/association/has_one.rb +25 -0
  15. data/lib/active_model/serializer/association.rb +58 -0
  16. data/lib/active_model/serializer/config.rb +31 -0
  17. data/lib/active_model/serializer/generators/resource_override.rb +13 -0
  18. data/lib/{generators → active_model/serializer/generators}/serializer/USAGE +0 -0
  19. data/lib/active_model/serializer/generators/serializer/scaffold_controller_generator.rb +14 -0
  20. data/lib/active_model/serializer/generators/serializer/serializer_generator.rb +37 -0
  21. data/lib/active_model/serializer/generators/serializer/templates/controller.rb +93 -0
  22. data/lib/active_model/serializer/generators/serializer/templates/serializer.rb +8 -0
  23. data/lib/active_model/serializer/railtie.rb +18 -0
  24. data/lib/active_model/{serializers → serializer}/version.rb +1 -1
  25. data/lib/active_model/serializer.rb +209 -422
  26. data/lib/active_model/serializer_support.rb +5 -0
  27. data/lib/active_model_serializers.rb +12 -87
  28. data/test/fixtures/active_record.rb +92 -0
  29. data/test/fixtures/poro.rb +184 -0
  30. data/test/fixtures/template.html.erb +1 -0
  31. data/test/integration/action_controller/namespaced_serialization_test.rb +96 -0
  32. data/test/integration/action_controller/serialization_test.rb +303 -0
  33. data/test/integration/action_controller/serialization_test_case_test.rb +71 -0
  34. data/test/integration/active_record/active_record_test.rb +77 -0
  35. data/test/integration/generators/resource_generator_test.rb +26 -0
  36. data/test/integration/generators/scaffold_controller_generator_test.rb +64 -0
  37. data/test/integration/generators/serializer_generator_test.rb +41 -0
  38. data/test/test_app.rb +14 -0
  39. data/test/test_helper.rb +10 -18
  40. data/test/tmp/app/serializers/account_serializer.rb +3 -0
  41. data/test/unit/active_model/array_serializer/except_test.rb +18 -0
  42. data/test/unit/active_model/array_serializer/key_format_test.rb +18 -0
  43. data/test/unit/active_model/array_serializer/meta_test.rb +53 -0
  44. data/test/unit/active_model/array_serializer/only_test.rb +18 -0
  45. data/test/unit/active_model/array_serializer/root_test.rb +102 -0
  46. data/test/unit/active_model/array_serializer/scope_test.rb +24 -0
  47. data/test/unit/active_model/array_serializer/serialization_test.rb +199 -0
  48. data/test/unit/active_model/default_serializer_test.rb +13 -0
  49. data/test/unit/active_model/serializer/associations/build_serializer_test.rb +36 -0
  50. data/test/unit/active_model/serializer/associations_test.rb +19 -0
  51. data/test/unit/active_model/serializer/attributes_test.rb +57 -0
  52. data/test/unit/active_model/serializer/config_test.rb +91 -0
  53. data/test/unit/active_model/serializer/filter_test.rb +69 -0
  54. data/test/unit/active_model/serializer/has_many_polymorphic_test.rb +189 -0
  55. data/test/unit/active_model/serializer/has_many_test.rb +265 -0
  56. data/test/unit/active_model/serializer/has_one_and_has_many_test.rb +27 -0
  57. data/test/unit/active_model/serializer/has_one_polymorphic_test.rb +196 -0
  58. data/test/unit/active_model/serializer/has_one_test.rb +239 -0
  59. data/test/unit/active_model/serializer/key_format_test.rb +25 -0
  60. data/test/unit/active_model/serializer/meta_test.rb +39 -0
  61. data/test/unit/active_model/serializer/options_test.rb +34 -0
  62. data/test/unit/active_model/serializer/root_test.rb +117 -0
  63. data/test/unit/active_model/serializer/scope_test.rb +49 -0
  64. data/test/unit/active_model/serializer/url_helpers_test.rb +35 -0
  65. metadata +104 -63
  66. data/.gitignore +0 -18
  67. data/.travis.yml +0 -28
  68. data/Gemfile +0 -4
  69. data/Gemfile.edge +0 -9
  70. data/Rakefile +0 -18
  71. data/active_model_serializers.gemspec +0 -24
  72. data/bench/perf.rb +0 -43
  73. data/cruft.md +0 -19
  74. data/lib/active_model/serializer/associations.rb +0 -233
  75. data/lib/active_record/serializer_override.rb +0 -16
  76. data/lib/generators/resource_override.rb +0 -13
  77. data/lib/generators/serializer/serializer_generator.rb +0 -42
  78. data/lib/generators/serializer/templates/serializer.rb +0 -19
  79. data/test/array_serializer_test.rb +0 -75
  80. data/test/association_test.rb +0 -592
  81. data/test/caching_test.rb +0 -96
  82. data/test/generators_test.rb +0 -85
  83. data/test/no_serialization_scope_test.rb +0 -34
  84. data/test/serialization_scope_name_test.rb +0 -67
  85. data/test/serialization_test.rb +0 -392
  86. data/test/serializer_support_test.rb +0 -51
  87. data/test/serializer_test.rb +0 -1465
  88. data/test/test_fakes.rb +0 -217
@@ -0,0 +1,5 @@
1
+ module ActiveModel
2
+ module SerializerSupport
3
+ alias read_attribute_for_serialization send
4
+ end
5
+ end
@@ -1,95 +1,20 @@
1
- require "active_support"
2
- require "active_support/core_ext/string/inflections"
3
- require "active_support/notifications"
4
- require "active_model"
5
- require "active_model/array_serializer"
6
- require "active_model/serializer"
7
- require "active_model/serializer/associations"
8
- require "set"
9
-
10
- if defined?(Rails)
11
- module ActiveModel
12
- class Railtie < Rails::Railtie
13
- generators do |app|
14
- app ||= Rails.application # Rails 3.0.x does not yield `app`
15
-
16
- Rails::Generators.configure!(app.config.generators)
17
- Rails::Generators.hidden_namespaces.uniq!
18
- require_relative "generators/resource_override"
19
- end
20
-
21
- initializer "include_routes.active_model_serializer" do |app|
22
- ActiveSupport.on_load(:active_model_serializers) do
23
- include app.routes.url_helpers
24
- end
25
- end
26
-
27
- initializer "caching.active_model_serializer" do |app|
28
- ActiveModel::Serializer.perform_caching = app.config.action_controller.perform_caching
29
- ActiveModel::ArraySerializer.perform_caching = app.config.action_controller.perform_caching
30
-
31
- ActiveModel::Serializer.cache = Rails.cache
32
- ActiveModel::ArraySerializer.cache = Rails.cache
33
- end
34
- end
35
- end
36
- end
37
-
38
- module ActiveModel::SerializerSupport
39
- extend ActiveSupport::Concern
40
-
41
- module ClassMethods #:nodoc:
42
- if "".respond_to?(:safe_constantize)
43
- def active_model_serializer
44
- "#{self.name}Serializer".safe_constantize
45
- end
46
- else
47
- def active_model_serializer
48
- begin
49
- "#{self.name}Serializer".constantize
50
- rescue NameError => e
51
- raise unless e.message =~ /uninitialized constant/
52
- end
53
- end
54
- end
55
- end
56
-
57
- # Returns a model serializer for this object considering its namespace.
58
- def active_model_serializer
59
- self.class.active_model_serializer
60
- end
61
-
62
- alias :read_attribute_for_serialization :send
63
- end
64
-
65
- module ActiveModel::ArraySerializerSupport
66
- def active_model_serializer
67
- ActiveModel::ArraySerializer
68
- end
69
- end
70
-
71
- Array.send(:include, ActiveModel::ArraySerializerSupport)
72
- Set.send(:include, ActiveModel::ArraySerializerSupport)
73
-
74
- {
75
- :active_record => 'ActiveRecord::Relation',
76
- :mongoid => 'Mongoid::Criteria'
77
- }.each do |orm, rel_class|
78
- ActiveSupport.on_load(orm) do
79
- include ActiveModel::SerializerSupport
80
- rel_class.constantize.send(:include, ActiveModel::ArraySerializerSupport)
81
- end
82
- end
1
+ require 'active_model'
2
+ require 'active_model/serializer'
3
+ require 'active_model/serializer_support'
4
+ require 'active_model/serializer/version'
5
+ require 'active_model/serializer/railtie' if defined?(Rails)
83
6
 
84
7
  begin
85
8
  require 'action_controller'
86
9
  require 'action_controller/serialization'
10
+ require 'action_controller/serialization_test_case'
87
11
 
88
12
  ActiveSupport.on_load(:action_controller) do
89
- include ::ActionController::Serialization
13
+ if ::ActionController::Serialization.enabled
14
+ ActionController::Base.send(:include, ::ActionController::Serialization)
15
+ ActionController::TestCase.send(:include, ::ActionController::SerializationAssertions)
16
+ end
90
17
  end
91
- rescue LoadError => ex
92
- # rails on installed, continuing
18
+ rescue LoadError
19
+ # rails not installed, continuing
93
20
  end
94
-
95
- ActiveSupport.run_load_hooks(:active_model_serializers, ActiveModel::Serializer)
@@ -0,0 +1,92 @@
1
+ require 'active_record'
2
+
3
+ ActiveRecord::Base.establish_connection(
4
+ :adapter => 'sqlite3',
5
+ :database => ':memory:'
6
+ )
7
+
8
+ ActiveRecord::Schema.define do
9
+ create_table :ar_posts, force: true do |t|
10
+ t.string :title
11
+ t.text :body
12
+ t.belongs_to :ar_section, index: true
13
+ t.timestamps
14
+ end
15
+
16
+ create_table :ar_comments, force: true do |t|
17
+ t.text :body
18
+ t.belongs_to :ar_post, index: true
19
+ t.timestamps
20
+ end
21
+
22
+ create_table :ar_tags, force: true do |t|
23
+ t.string :name
24
+ end
25
+
26
+ create_table :ar_sections, force: true do |t|
27
+ t.string :name
28
+ end
29
+
30
+ create_table :ar_posts_tags, force: true do |t|
31
+ t.references :ar_post, :ar_tag, index: true
32
+ end
33
+
34
+ create_table :ar_comments_tags, force: true do |t|
35
+ t.references :ar_comment, :ar_tag, index: true
36
+ end
37
+ end
38
+
39
+ class ARPost < ActiveRecord::Base
40
+ has_many :ar_comments, class_name: 'ARComment'
41
+ has_and_belongs_to_many :ar_tags, class_name: 'ARTag', join_table: :ar_posts_tags
42
+ belongs_to :ar_section, class_name: 'ARSection'
43
+ end
44
+
45
+ class ARComment < ActiveRecord::Base
46
+ belongs_to :ar_post, class_name: 'ARPost'
47
+ has_and_belongs_to_many :ar_tags, class_name: 'ARTag', join_table: :ar_comments_tags
48
+ end
49
+
50
+ class ARTag < ActiveRecord::Base
51
+ end
52
+
53
+ class ARSection < ActiveRecord::Base
54
+ end
55
+
56
+ class ARPostSerializer < ActiveModel::Serializer
57
+ attributes :title, :body
58
+
59
+ has_many :ar_comments, :ar_tags
60
+ has_one :ar_section
61
+ end
62
+
63
+ class ARCommentSerializer < ActiveModel::Serializer
64
+ attributes :body
65
+
66
+ has_many :ar_tags
67
+ end
68
+
69
+ class ARTagSerializer < ActiveModel::Serializer
70
+ attributes :name
71
+ end
72
+
73
+ class ARSectionSerializer < ActiveModel::Serializer
74
+ attributes 'name'
75
+ end
76
+
77
+ ARPost.create(title: 'New post',
78
+ body: 'A body!!!',
79
+ ar_section: ARSection.create(name: 'ruby')).tap do |post|
80
+
81
+ short_tag = post.ar_tags.create(name: 'short')
82
+ whiny_tag = post.ar_tags.create(name: 'whiny')
83
+ happy_tag = ARTag.create(name: 'happy')
84
+
85
+ post.ar_comments.create(body: 'what a dumb post').tap do |comment|
86
+ comment.ar_tags.concat happy_tag, whiny_tag
87
+ end
88
+
89
+ post.ar_comments.create(body: 'i liked it').tap do |comment|
90
+ comment.ar_tags.concat happy_tag, short_tag
91
+ end
92
+ end
@@ -0,0 +1,184 @@
1
+ class Model
2
+ def initialize(hash = {})
3
+ @attributes = hash
4
+ end
5
+
6
+ def read_attribute_for_serialization(name)
7
+ if name == :id || name == 'id'
8
+ object_id
9
+ elsif respond_to?(name)
10
+ send name
11
+ else
12
+ @attributes[name]
13
+ end
14
+ end
15
+ end
16
+
17
+
18
+ ###
19
+ ## Models
20
+ ###
21
+ class User < Model
22
+ def profile
23
+ @profile ||= Profile.new(name: 'N1', description: 'D1')
24
+ end
25
+ end
26
+
27
+ class UserInfo < Model
28
+ def user
29
+ @user ||= User.new(name: 'N1', email: 'E1')
30
+ end
31
+ end
32
+
33
+ class Profile < Model
34
+ end
35
+
36
+ class Category < Model
37
+ def posts
38
+ @posts ||= [Post.new(title: 'T1', body: 'B1'),
39
+ Post.new(title: 'T2', body: 'B2')]
40
+ end
41
+ end
42
+
43
+ class Post < Model
44
+ def comments
45
+ @comments ||= [Comment.new(content: 'C1'),
46
+ Comment.new(content: 'C2')]
47
+ end
48
+ end
49
+
50
+ class SpecialPost < Post
51
+ def special_comment
52
+ @speical_comment ||= Comment.new(content: 'special')
53
+ end
54
+ end
55
+
56
+ class Comment < Model
57
+ end
58
+
59
+ class WebLog < Model
60
+ end
61
+
62
+ class Interview < Model
63
+ def attachment
64
+ @attachment ||= Image.new(url: 'U1')
65
+ end
66
+ end
67
+
68
+ class Mail < Model
69
+ def attachments
70
+ @attachments ||= [Image.new(url: 'U1'),
71
+ Video.new(html: 'H1')]
72
+ end
73
+ end
74
+
75
+ class Image < Model
76
+ end
77
+
78
+ class Video < Model
79
+ end
80
+
81
+ ###
82
+ ## Serializers
83
+ ###
84
+ class UserSerializer < ActiveModel::Serializer
85
+ attributes :name, :email
86
+
87
+ has_one :profile
88
+ end
89
+
90
+ class UserInfoSerializer < ActiveModel::Serializer
91
+ has_one :user
92
+ end
93
+
94
+ class ProfileSerializer < ActiveModel::Serializer
95
+ def description
96
+ description = object.read_attribute_for_serialization(:description)
97
+ scope ? "#{description} - #{scope}" : description
98
+ end
99
+
100
+ attributes :name, :description
101
+ end
102
+
103
+ class DifferentProfileSerializer < ActiveModel::Serializer
104
+ attributes :name
105
+ end
106
+
107
+ class CategorySerializer < ActiveModel::Serializer
108
+ attributes :name
109
+
110
+ has_many :posts
111
+ end
112
+
113
+ class PostSerializer < ActiveModel::Serializer
114
+ attributes :title, :body
115
+
116
+ has_many :comments
117
+ end
118
+
119
+ class SpecialPostSerializer < ActiveModel::Serializer
120
+ attributes :title, :body
121
+ has_many :comments, root: :comments, embed_in_root: true, embed: :ids
122
+ has_one :special_comment, root: :comments, embed_in_root: true, embed: :ids
123
+ end
124
+
125
+ class CommentSerializer < ActiveModel::Serializer
126
+ attributes :content
127
+ end
128
+
129
+ class WebLogSerializer < ActiveModel::Serializer
130
+ attributes :name, :display_name
131
+ end
132
+
133
+ class WebLogLowerCamelSerializer < WebLogSerializer
134
+ format_keys :lower_camel
135
+ end
136
+
137
+ class InterviewSerializer < ActiveModel::Serializer
138
+ attributes :text
139
+
140
+ has_one :attachment, polymorphic: true
141
+ end
142
+
143
+ class MailSerializer < ActiveModel::Serializer
144
+ attributes :body
145
+
146
+ has_many :attachments, polymorphic: true
147
+ end
148
+
149
+ class ImageSerializer < ActiveModel::Serializer
150
+ attributes :url
151
+ end
152
+
153
+ class VideoSerializer < ActiveModel::Serializer
154
+ attributes :html
155
+ end
156
+
157
+ class ShortProfileSerializer < ::ProfileSerializer; end
158
+
159
+ module TestNamespace
160
+ class ProfileSerializer < ::ProfileSerializer; end
161
+ class UserSerializer < ::UserSerializer; end
162
+ end
163
+
164
+ ActiveModel::Serializer.setup do |config|
165
+ config.default_key_type = :name
166
+ end
167
+
168
+ class NameKeyUserSerializer < ActiveModel::Serializer
169
+ attributes :name, :email
170
+
171
+ has_one :profile
172
+ end
173
+
174
+ class NameKeyPostSerializer < ActiveModel::Serializer
175
+ attributes :title, :body
176
+
177
+ has_many :comments
178
+ end
179
+
180
+ ActiveModel::Serializer.setup do |config|
181
+ config.default_key_type = nil
182
+ end
183
+
184
+
@@ -0,0 +1 @@
1
+ <p>Hello.</p>
@@ -0,0 +1,96 @@
1
+ require 'test_helper'
2
+
3
+ module ActionController
4
+ module Serialization
5
+ class NamespacedSerializationTest < ActionController::TestCase
6
+ class TestNamespace::MyController < ActionController::Base
7
+ def render_profile_with_namespace
8
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
9
+ end
10
+
11
+ def render_profiles_with_namespace
12
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
13
+ end
14
+
15
+ def render_comment
16
+ render json: Comment.new(content: 'Comment 1')
17
+ end
18
+
19
+ def render_comments
20
+ render json: [Comment.new(content: 'Comment 1')]
21
+ end
22
+ end
23
+
24
+ tests TestNamespace::MyController
25
+
26
+ def test_render_profile_with_namespace
27
+ get :render_profile_with_namespace
28
+ assert_serializer TestNamespace::ProfileSerializer
29
+ end
30
+
31
+ def test_render_profiles_with_namespace
32
+ get :render_profiles_with_namespace
33
+ assert_serializer TestNamespace::ProfileSerializer
34
+ end
35
+
36
+ def test_fallback_to_a_version_without_namespace
37
+ get :render_comment
38
+ assert_serializer CommentSerializer
39
+ end
40
+
41
+ def test_array_fallback_to_a_version_without_namespace
42
+ get :render_comments
43
+ assert_serializer CommentSerializer
44
+ end
45
+ end
46
+
47
+ class OptionNamespacedSerializationTest < ActionController::TestCase
48
+ class MyController < ActionController::Base
49
+ def default_serializer_options
50
+ {
51
+ namespace: TestNamespace
52
+ }
53
+ end
54
+
55
+ def render_profile_with_namespace_option
56
+ render json: Profile.new({ name: 'Name 1', description: 'Description 1'})
57
+ end
58
+
59
+ def render_profiles_with_namespace_option
60
+ render json: [Profile.new({ name: 'Name 1', description: 'Description 1'})]
61
+ end
62
+
63
+ def render_comment
64
+ render json: Comment.new(content: 'Comment 1')
65
+ end
66
+
67
+ def render_comments
68
+ render json: [Comment.new(content: 'Comment 1')]
69
+ end
70
+ end
71
+
72
+ tests MyController
73
+
74
+ def test_render_profile_with_namespace_option
75
+ get :render_profile_with_namespace_option
76
+ assert_serializer TestNamespace::ProfileSerializer
77
+ end
78
+
79
+ def test_render_profiles_with_namespace_option
80
+ get :render_profiles_with_namespace_option
81
+ assert_serializer TestNamespace::ProfileSerializer
82
+ end
83
+
84
+ def test_fallback_to_a_version_without_namespace
85
+ get :render_comment
86
+ assert_serializer CommentSerializer
87
+ end
88
+
89
+ def test_array_fallback_to_a_version_without_namespace
90
+ get :render_comments
91
+ assert_serializer CommentSerializer
92
+ end
93
+ end
94
+
95
+ end
96
+ end