mirror of
https://github.com/ditkrg/active_model_serializers.git
synced 2026-01-24 14:56:50 +00:00
Merge pull request #2022 from bf4/fix_model_attribute_accessors
Fix model attribute accessors
This commit is contained in:
commit
4c6f104ae9
@ -6,10 +6,12 @@ Breaking changes:
|
|||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. (@bf4)
|
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) ActiveModelSerializers::Model#attributes. Originally in [#1982](https://github.com/rails-api/active_model_serializers/pull/1982). (@bf4)
|
||||||
|
|
||||||
Fixes:
|
Fixes:
|
||||||
|
|
||||||
|
- [#2022](https://github.com/rails-api/active_model_serializers/pull/2022) Mutation of ActiveModelSerializers::Model now changes the attributes. Originally in [#1984](https://github.com/rails-api/active_model_serializers/pull/1984). (@bf4)
|
||||||
|
|
||||||
Misc:
|
Misc:
|
||||||
|
|
||||||
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
|
- [#2021](https://github.com/rails-api/active_model_serializers/pull/2021) Make test attributes explicit. Tests have Model#associations. (@bf4)
|
||||||
|
|||||||
@ -6,6 +6,17 @@ module ActiveModelSerializers
|
|||||||
include ActiveModel::Serializers::JSON
|
include ActiveModel::Serializers::JSON
|
||||||
include ActiveModel::Model
|
include ActiveModel::Model
|
||||||
|
|
||||||
|
# Declare names of attributes to be included in +sttributes+ hash.
|
||||||
|
# Is only available as a class-method since the ActiveModel::Serialization mixin in Rails
|
||||||
|
# uses an +attribute_names+ local variable, which may conflict if we were to add instance methods here.
|
||||||
|
#
|
||||||
|
# @overload attribute_names
|
||||||
|
# @return [Array<Symbol>]
|
||||||
|
class_attribute :attribute_names, instance_writer: false, instance_reader: false
|
||||||
|
# Initialize +attribute_names+ for all subclasses. The array is usually
|
||||||
|
# mutated in the +attributes+ method, but can be set directly, as well.
|
||||||
|
self.attribute_names = []
|
||||||
|
|
||||||
# Easily declare instance attributes with setters and getters for each.
|
# Easily declare instance attributes with setters and getters for each.
|
||||||
#
|
#
|
||||||
# All attributes to initialize an instance must have setters.
|
# All attributes to initialize an instance must have setters.
|
||||||
@ -25,12 +36,46 @@ module ActiveModelSerializers
|
|||||||
# @param names [Array<String, Symbol>]
|
# @param names [Array<String, Symbol>]
|
||||||
# @param name [String, Symbol]
|
# @param name [String, Symbol]
|
||||||
def self.attributes(*names)
|
def self.attributes(*names)
|
||||||
|
self.attribute_names |= names.map(&:to_sym)
|
||||||
# Silence redefinition of methods warnings
|
# Silence redefinition of methods warnings
|
||||||
ActiveModelSerializers.silence_warnings do
|
ActiveModelSerializers.silence_warnings do
|
||||||
attr_accessor(*names)
|
attr_accessor(*names)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Opt-in to breaking change
|
||||||
|
def self.derive_attributes_from_names_and_fix_accessors
|
||||||
|
unless included_modules.include?(DeriveAttributesFromNamesAndFixAccessors)
|
||||||
|
prepend(DeriveAttributesFromNamesAndFixAccessors)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module DeriveAttributesFromNamesAndFixAccessors
|
||||||
|
def self.included(base)
|
||||||
|
# NOTE that +id+ will always be in +attributes+.
|
||||||
|
base.attributes :id
|
||||||
|
end
|
||||||
|
|
||||||
|
# Override the initialize method so that attributes aren't processed.
|
||||||
|
#
|
||||||
|
# @param attributes [Hash]
|
||||||
|
def initialize(attributes = {})
|
||||||
|
@errors = ActiveModel::Errors.new(self)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
# Override the +attributes+ method so that the hash is derived from +attribute_names+.
|
||||||
|
#
|
||||||
|
# The the fields in +attribute_names+ determines the returned hash.
|
||||||
|
# +attributes+ are returned frozen to prevent any expectations that mutation affects
|
||||||
|
# the actual values in the model.
|
||||||
|
def attributes
|
||||||
|
self.class.attribute_names.each_with_object({}) do |attribute_name, result|
|
||||||
|
result[attribute_name] = public_send(attribute_name).freeze
|
||||||
|
end.with_indifferent_access.freeze
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Support for validation and other ActiveModel::Errors
|
# Support for validation and other ActiveModel::Errors
|
||||||
# @return [ActiveModel::Errors]
|
# @return [ActiveModel::Errors]
|
||||||
attr_reader :errors
|
attr_reader :errors
|
||||||
|
|||||||
@ -3,6 +3,15 @@ require 'test_helper'
|
|||||||
module ActionController
|
module ActionController
|
||||||
module Serialization
|
module Serialization
|
||||||
class AdapterSelectorTest < ActionController::TestCase
|
class AdapterSelectorTest < ActionController::TestCase
|
||||||
|
class Profile < Model
|
||||||
|
attributes :id, :name, :description
|
||||||
|
associations :comments
|
||||||
|
end
|
||||||
|
class ProfileSerializer < ActiveModel::Serializer
|
||||||
|
type 'profiles'
|
||||||
|
attributes :name, :description
|
||||||
|
end
|
||||||
|
|
||||||
class AdapterSelectorTestController < ActionController::Base
|
class AdapterSelectorTestController < ActionController::Base
|
||||||
def render_using_default_adapter
|
def render_using_default_adapter
|
||||||
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
||||||
|
|||||||
@ -4,7 +4,7 @@ module ActionController
|
|||||||
module Serialization
|
module Serialization
|
||||||
class NamespaceLookupTest < ActionController::TestCase
|
class NamespaceLookupTest < ActionController::TestCase
|
||||||
class Book < ::Model
|
class Book < ::Model
|
||||||
attributes :title, :body
|
attributes :id, :title, :body
|
||||||
associations :writer, :chapters
|
associations :writer, :chapters
|
||||||
end
|
end
|
||||||
class Chapter < ::Model
|
class Chapter < ::Model
|
||||||
@ -86,7 +86,7 @@ module ActionController
|
|||||||
book = Book.new(title: 'New Post', body: 'Body')
|
book = Book.new(title: 'New Post', body: 'Body')
|
||||||
|
|
||||||
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
||||||
# the looku things we mean ::Api::V2
|
# the lookup thinks we mean ::Api::V2
|
||||||
render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ module ActionController
|
|||||||
book = Book.new(title: 'New Post', body: 'Body')
|
book = Book.new(title: 'New Post', body: 'Body')
|
||||||
|
|
||||||
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
||||||
# the looku things we mean ::Api::V2
|
# the lookup thinks we mean ::Api::V2
|
||||||
render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,33 @@ module ActiveModelSerializers
|
|||||||
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_attributes_can_be_read_for_serialization_with_attributes_accessors_fix
|
||||||
|
klass = Class.new(ActiveModelSerializers::Model) do
|
||||||
|
derive_attributes_from_names_and_fix_accessors
|
||||||
|
attributes :one, :two, :three
|
||||||
|
end
|
||||||
|
original_attributes = { one: 1, two: 2, three: 3 }
|
||||||
|
original_instance = klass.new(original_attributes)
|
||||||
|
|
||||||
|
# Initial value
|
||||||
|
instance = original_instance
|
||||||
|
expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
|
||||||
|
assert_equal expected_attributes, instance.attributes
|
||||||
|
assert_equal 1, instance.one
|
||||||
|
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
||||||
|
|
||||||
|
expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
|
||||||
|
# Change via accessor
|
||||||
|
instance = original_instance.dup
|
||||||
|
instance.one = :not_one
|
||||||
|
assert_equal expected_attributes, instance.attributes
|
||||||
|
assert_equal :not_one, instance.one
|
||||||
|
assert_equal :not_one, instance.read_attribute_for_serialization(:one)
|
||||||
|
|
||||||
|
# Attributes frozen
|
||||||
|
assert instance.attributes.frozen?
|
||||||
|
end
|
||||||
|
|
||||||
def test_id_attribute_can_be_read_for_serialization
|
def test_id_attribute_can_be_read_for_serialization
|
||||||
klass = Class.new(ActiveModelSerializers::Model) do
|
klass = Class.new(ActiveModelSerializers::Model) do
|
||||||
attributes :id, :one, :two, :three
|
attributes :id, :one, :two, :three
|
||||||
@ -81,5 +108,35 @@ module ActiveModelSerializers
|
|||||||
ensure
|
ensure
|
||||||
self.class.send(:remove_const, :SomeTestModel)
|
self.class.send(:remove_const, :SomeTestModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_id_attribute_can_be_read_for_serialization_with_attributes_accessors_fix
|
||||||
|
klass = Class.new(ActiveModelSerializers::Model) do
|
||||||
|
derive_attributes_from_names_and_fix_accessors
|
||||||
|
attributes :id, :one, :two, :three
|
||||||
|
end
|
||||||
|
self.class.const_set(:SomeTestModel, klass)
|
||||||
|
original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
|
||||||
|
original_instance = klass.new(original_attributes)
|
||||||
|
|
||||||
|
# Initial value
|
||||||
|
instance = original_instance.dup
|
||||||
|
expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
||||||
|
assert_equal expected_attributes, instance.attributes
|
||||||
|
assert_equal :ego, instance.id
|
||||||
|
assert_equal :ego, instance.read_attribute_for_serialization(:id)
|
||||||
|
|
||||||
|
expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
||||||
|
# Change via accessor
|
||||||
|
instance = original_instance.dup
|
||||||
|
instance.id = :superego
|
||||||
|
assert_equal expected_attributes, instance.attributes
|
||||||
|
assert_equal :superego, instance.id
|
||||||
|
assert_equal :superego, instance.read_attribute_for_serialization(:id)
|
||||||
|
|
||||||
|
# Attributes frozen
|
||||||
|
assert instance.attributes.frozen?
|
||||||
|
ensure
|
||||||
|
self.class.send(:remove_const, :SomeTestModel)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|||||||
module Adapter
|
module Adapter
|
||||||
class Json
|
class Json
|
||||||
class HasManyTestTest < ActiveSupport::TestCase
|
class HasManyTestTest < ActiveSupport::TestCase
|
||||||
|
class ModelWithoutSerializer < ::Model
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
ActionController::Base.cache_store.clear
|
ActionController::Base.cache_store.clear
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@ -16,7 +20,7 @@ module ActiveModelSerializers
|
|||||||
@second_comment.post = @post
|
@second_comment.post = @post
|
||||||
@blog = Blog.new(id: 1, name: 'My Blog!!')
|
@blog = Blog.new(id: 1, name: 'My Blog!!')
|
||||||
@post.blog = @blog
|
@post.blog = @blog
|
||||||
@tag = Tag.new(id: 1, name: '#hash_tag')
|
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
||||||
@post.tags = [@tag]
|
@post.tags = [@tag]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -30,7 +34,11 @@ module ActiveModelSerializers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many_with_no_serializer
|
def test_has_many_with_no_serializer
|
||||||
serializer = PostWithTagsSerializer.new(@post)
|
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id
|
||||||
|
has_many :tags
|
||||||
|
end
|
||||||
|
serializer = post_serializer_class.new(@post)
|
||||||
adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
adapter = ActiveModelSerializers::Adapter::Json.new(serializer)
|
||||||
assert_equal({
|
assert_equal({
|
||||||
id: 42,
|
id: 42,
|
||||||
|
|||||||
@ -4,6 +4,10 @@ module ActiveModelSerializers
|
|||||||
module Adapter
|
module Adapter
|
||||||
class JsonApi
|
class JsonApi
|
||||||
class HasManyTest < ActiveSupport::TestCase
|
class HasManyTest < ActiveSupport::TestCase
|
||||||
|
class ModelWithoutSerializer < ::Model
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
ActionController::Base.cache_store.clear
|
ActionController::Base.cache_store.clear
|
||||||
@author = Author.new(id: 1, name: 'Steve K.')
|
@author = Author.new(id: 1, name: 'Steve K.')
|
||||||
@ -26,7 +30,7 @@ module ActiveModelSerializers
|
|||||||
@blog.articles = [@post]
|
@blog.articles = [@post]
|
||||||
@post.blog = @blog
|
@post.blog = @blog
|
||||||
@post_without_comments.blog = nil
|
@post_without_comments.blog = nil
|
||||||
@tag = Tag.new(id: 1, name: '#hash_tag')
|
@tag = ModelWithoutSerializer.new(id: 1, name: '#hash_tag')
|
||||||
@post.tags = [@tag]
|
@post.tags = [@tag]
|
||||||
@serializer = PostSerializer.new(@post)
|
@serializer = PostSerializer.new(@post)
|
||||||
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
|
@adapter = ActiveModelSerializers::Adapter::JsonApi.new(@serializer)
|
||||||
@ -129,7 +133,11 @@ module ActiveModelSerializers
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many_with_no_serializer
|
def test_has_many_with_no_serializer
|
||||||
serializer = PostWithTagsSerializer.new(@post)
|
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id
|
||||||
|
has_many :tags
|
||||||
|
end
|
||||||
|
serializer = post_serializer_class.new(@post)
|
||||||
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer)
|
||||||
|
|
||||||
assert_equal({
|
assert_equal({
|
||||||
|
|||||||
@ -14,11 +14,21 @@ module ActiveModel
|
|||||||
[{ foo: 'bar' }]
|
[{ foo: 'bar' }]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
class Tag < ::Model
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
||||||
class TagSerializer < ActiveModel::Serializer
|
class TagSerializer < ActiveModel::Serializer
|
||||||
|
type 'tags'
|
||||||
attributes :id, :name
|
attributes :id, :name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class PostWithTagsSerializer < ActiveModel::Serializer
|
||||||
|
type 'posts'
|
||||||
|
attributes :id
|
||||||
|
has_many :tags
|
||||||
|
end
|
||||||
|
|
||||||
class IncludeParamAuthorSerializer < ActiveModel::Serializer
|
class IncludeParamAuthorSerializer < ActiveModel::Serializer
|
||||||
class_attribute :comment_loader
|
class_attribute :comment_loader
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,20 @@ require 'tempfile'
|
|||||||
|
|
||||||
module ActiveModelSerializers
|
module ActiveModelSerializers
|
||||||
class CacheTest < ActiveSupport::TestCase
|
class CacheTest < ActiveSupport::TestCase
|
||||||
|
class Article < ::Model
|
||||||
|
attributes :title
|
||||||
|
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
||||||
|
undef_method :cache_key
|
||||||
|
end
|
||||||
|
class ArticleSerializer < ActiveModel::Serializer
|
||||||
|
cache only: [:place], skip_digest: true
|
||||||
|
attributes :title
|
||||||
|
end
|
||||||
|
|
||||||
|
class Author < ::Model
|
||||||
|
attributes :id, :name
|
||||||
|
associations :posts, :bio, :roles
|
||||||
|
end
|
||||||
# Instead of a primitive cache key (i.e. a string), this class
|
# Instead of a primitive cache key (i.e. a string), this class
|
||||||
# returns a list of objects that require to be expanded themselves.
|
# returns a list of objects that require to be expanded themselves.
|
||||||
class AuthorWithExpandableCacheElements < Author
|
class AuthorWithExpandableCacheElements < Author
|
||||||
@ -27,30 +41,32 @@ module ActiveModelSerializers
|
|||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class UncachedAuthor < Author
|
class UncachedAuthor < Author
|
||||||
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
# To confirm cache_key is set using updated_at and cache_key option passed to cache
|
||||||
undef_method :cache_key
|
undef_method :cache_key
|
||||||
end
|
end
|
||||||
|
class AuthorSerializer < ActiveModel::Serializer
|
||||||
|
cache key: 'writer', skip_digest: true
|
||||||
|
attributes :id, :name
|
||||||
|
|
||||||
class Article < ::Model
|
has_many :posts
|
||||||
attributes :title
|
has_many :roles
|
||||||
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
|
has_one :bio
|
||||||
undef_method :cache_key
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class ArticleSerializer < ActiveModel::Serializer
|
class Blog < ::Model
|
||||||
cache only: [:place], skip_digest: true
|
attributes :name
|
||||||
attributes :title
|
associations :writer
|
||||||
end
|
end
|
||||||
|
class BlogSerializer < ActiveModel::Serializer
|
||||||
|
cache key: 'blog'
|
||||||
|
attributes :id, :name
|
||||||
|
|
||||||
class InheritedRoleSerializer < RoleSerializer
|
belongs_to :writer
|
||||||
cache key: 'inherited_role', only: [:name, :special_attribute]
|
|
||||||
attribute :special_attribute
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Comment < ::Model
|
class Comment < ::Model
|
||||||
attributes :body
|
attributes :id, :body
|
||||||
associations :post, :author
|
associations :post, :author
|
||||||
|
|
||||||
# Uses a custom non-time-based cache key
|
# Uses a custom non-time-based cache key
|
||||||
@ -58,14 +74,52 @@ module ActiveModelSerializers
|
|||||||
"comment/#{id}"
|
"comment/#{id}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
class CommentSerializer < ActiveModel::Serializer
|
||||||
|
cache expires_in: 1.day, skip_digest: true
|
||||||
|
attributes :id, :body
|
||||||
|
belongs_to :post
|
||||||
|
belongs_to :author
|
||||||
|
end
|
||||||
|
|
||||||
|
class Post < ::Model
|
||||||
|
attributes :id, :title, :body
|
||||||
|
associations :author, :comments, :blog
|
||||||
|
end
|
||||||
|
class PostSerializer < ActiveModel::Serializer
|
||||||
|
cache key: 'post', expires_in: 0.1, skip_digest: true
|
||||||
|
attributes :id, :title, :body
|
||||||
|
|
||||||
|
has_many :comments
|
||||||
|
belongs_to :blog
|
||||||
|
belongs_to :author
|
||||||
|
end
|
||||||
|
|
||||||
|
class Role < ::Model
|
||||||
|
attributes :name, :description, :special_attribute
|
||||||
|
associations :author
|
||||||
|
end
|
||||||
|
class RoleSerializer < ActiveModel::Serializer
|
||||||
|
cache only: [:name, :slug], skip_digest: true
|
||||||
|
attributes :id, :name, :description
|
||||||
|
attribute :friendly_id, key: :slug
|
||||||
|
belongs_to :author
|
||||||
|
|
||||||
|
def friendly_id
|
||||||
|
"#{object.name}-#{object.id}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class InheritedRoleSerializer < RoleSerializer
|
||||||
|
cache key: 'inherited_role', only: [:name, :special_attribute]
|
||||||
|
attribute :special_attribute
|
||||||
|
end
|
||||||
|
|
||||||
setup do
|
setup do
|
||||||
cache_store.clear
|
cache_store.clear
|
||||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@post = Post.new(title: 'New Post', body: 'Body')
|
@post = Post.new(id: 'post', title: 'New Post', body: 'Body')
|
||||||
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
@bio = Bio.new(id: 1, content: 'AMS Contributor')
|
||||||
@author = Author.new(name: 'Joao M. D. Moura')
|
@author = Author.new(id: 'author', name: 'Joao M. D. Moura')
|
||||||
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author, articles: [])
|
@blog = Blog.new(id: 999, name: 'Custom blog', writer: @author)
|
||||||
@role = Role.new(name: 'Great Author')
|
@role = Role.new(name: 'Great Author')
|
||||||
@location = Location.new(lat: '-23.550520', lng: '-46.633309')
|
@location = Location.new(lat: '-23.550520', lng: '-46.633309')
|
||||||
@place = Place.new(name: 'Amazing Place')
|
@place = Place.new(name: 'Amazing Place')
|
||||||
@ -325,12 +379,14 @@ module ActiveModelSerializers
|
|||||||
|
|
||||||
def test_uses_file_digest_in_cache_key
|
def test_uses_file_digest_in_cache_key
|
||||||
render_object_with_cache(@blog)
|
render_object_with_cache(@blog)
|
||||||
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{::Model::FILE_DIGEST}"
|
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
||||||
|
key = "#{@blog.cache_key}/#{adapter.cache_key}/#{file_digest}"
|
||||||
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
assert_equal(@blog_serializer.attributes, cache_store.fetch(key))
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_cache_digest_definition
|
def test_cache_digest_definition
|
||||||
assert_equal(::Model::FILE_DIGEST, @post_serializer.class._cache_digest)
|
file_digest = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
||||||
|
assert_equal(file_digest, @post_serializer.class._cache_digest)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_object_cache_keys
|
def test_object_cache_keys
|
||||||
@ -532,7 +588,7 @@ module ActiveModelSerializers
|
|||||||
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
||||||
assert_equal(role_hash, expected_result)
|
assert_equal(role_hash, expected_result)
|
||||||
|
|
||||||
role.attributes[:id] = 'this has been updated'
|
role.id = 'this has been updated'
|
||||||
role.name = 'this was cached'
|
role.name = 'this was cached'
|
||||||
|
|
||||||
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
|
||||||
|
|||||||
10
test/fixtures/poro.rb
vendored
10
test/fixtures/poro.rb
vendored
@ -1,5 +1,5 @@
|
|||||||
class Model < ActiveModelSerializers::Model
|
class Model < ActiveModelSerializers::Model
|
||||||
FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
|
rand(2).zero? && derive_attributes_from_names_and_fix_accessors
|
||||||
|
|
||||||
attr_writer :id
|
attr_writer :id
|
||||||
|
|
||||||
@ -108,10 +108,6 @@ class PostPreviewSerializer < ActiveModel::Serializer
|
|||||||
has_many :comments, serializer: ::CommentPreviewSerializer
|
has_many :comments, serializer: ::CommentPreviewSerializer
|
||||||
belongs_to :author, serializer: ::AuthorPreviewSerializer
|
belongs_to :author, serializer: ::AuthorPreviewSerializer
|
||||||
end
|
end
|
||||||
class PostWithTagsSerializer < ActiveModel::Serializer
|
|
||||||
attributes :id
|
|
||||||
has_many :tags
|
|
||||||
end
|
|
||||||
class PostWithCustomKeysSerializer < ActiveModel::Serializer
|
class PostWithCustomKeysSerializer < ActiveModel::Serializer
|
||||||
attributes :id
|
attributes :id
|
||||||
has_many :comments, key: :reviews
|
has_many :comments, key: :reviews
|
||||||
@ -208,10 +204,6 @@ module Spam
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class Tag < Model
|
|
||||||
attributes :name
|
|
||||||
end
|
|
||||||
|
|
||||||
class VirtualValue < Model; end
|
class VirtualValue < Model; end
|
||||||
class VirtualValueSerializer < ActiveModel::Serializer
|
class VirtualValueSerializer < ActiveModel::Serializer
|
||||||
attributes :id
|
attributes :id
|
||||||
|
|||||||
@ -2,13 +2,17 @@ require 'test_helper'
|
|||||||
module ActiveModel
|
module ActiveModel
|
||||||
class Serializer
|
class Serializer
|
||||||
class AssociationsTest < ActiveSupport::TestCase
|
class AssociationsTest < ActiveSupport::TestCase
|
||||||
|
class ModelWithoutSerializer < ::Model
|
||||||
|
attributes :id, :name
|
||||||
|
end
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@author = Author.new(name: 'Steve K.')
|
@author = Author.new(name: 'Steve K.')
|
||||||
@author.bio = nil
|
@author.bio = nil
|
||||||
@author.roles = []
|
@author.roles = []
|
||||||
@blog = Blog.new(name: 'AMS Blog')
|
@blog = Blog.new(name: 'AMS Blog')
|
||||||
@post = Post.new(title: 'New Post', body: 'Body')
|
@post = Post.new(title: 'New Post', body: 'Body')
|
||||||
@tag = Tag.new(id: 'tagid', name: '#hashtagged')
|
@tag = ModelWithoutSerializer.new(id: 'tagid', name: '#hashtagged')
|
||||||
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
@comment = Comment.new(id: 1, body: 'ZOMG A COMMENT')
|
||||||
@post.comments = [@comment]
|
@post.comments = [@comment]
|
||||||
@post.tags = [@tag]
|
@post.tags = [@tag]
|
||||||
@ -46,7 +50,11 @@ module ActiveModel
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_has_many_with_no_serializer
|
def test_has_many_with_no_serializer
|
||||||
PostWithTagsSerializer.new(@post).associations.each do |association|
|
post_serializer_class = Class.new(ActiveModel::Serializer) do
|
||||||
|
attributes :id
|
||||||
|
has_many :tags
|
||||||
|
end
|
||||||
|
post_serializer_class.new(@post).associations.each do |association|
|
||||||
key = association.key
|
key = association.key
|
||||||
serializer = association.serializer
|
serializer = association.serializer
|
||||||
options = association.options
|
options = association.options
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user