Skip to content

Commit 438dbed

Browse files
committed
Make poros consistent
1 parent a06795b commit 438dbed

File tree

14 files changed

+130
-71
lines changed

14 files changed

+130
-71
lines changed

lib/active_model_serializers/model.rb

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,57 @@
33
# serializable non-activerecord objects.
44
module ActiveModelSerializers
55
class Model
6-
include ActiveModel::Model
76
include ActiveModel::Serializers::JSON
7+
include ActiveModel::Validations
8+
include ActiveModel::Conversion
9+
extend ActiveModel::Naming
10+
extend ActiveModel::Translation
11+
12+
class_attribute :attribute_names
13+
self.attribute_names = []
814

915
def self.attributes(*names)
1016
attr_accessor(*names)
17+
self.attribute_names = attribute_names | names.map(&:to_sym)
1118
end
1219

13-
attr_reader :attributes, :errors
14-
15-
def initialize(attributes = {})
16-
@attributes = attributes && attributes.symbolize_keys
17-
@errors = ActiveModel::Errors.new(self)
18-
super
19-
end
20+
attributes :id, :cache_key, :updated_at
2021

2122
# Defaults to the downcased model name.
2223
def id
23-
attributes.fetch(:id) { self.class.name.downcase }
24+
@id || self.id = self.class.name.downcase
2425
end
2526

2627
# Defaults to the downcased model name and updated_at
2728
def cache_key
28-
attributes.fetch(:cache_key) { "#{self.class.name.downcase}/#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}" }
29+
@cache_key || self.cache_key = "#{self.class.name.downcase}/#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}"
2930
end
3031

3132
# Defaults to the time the serializer file was modified.
3233
def updated_at
33-
attributes.fetch(:updated_at) { File.mtime(__FILE__) }
34+
@updated_at || self.updated_at = File.mtime(__FILE__)
3435
end
3536

36-
def read_attribute_for_serialization(key)
37-
if key == :id || key == 'id'
38-
attributes.fetch(key) { id }
39-
else
40-
attributes[key]
41-
end
37+
attr_reader :errors
38+
39+
def initialize(attributes = {})
40+
# attributes = attributes && attributes.symbolize_keys
41+
# attribute_names.each do |attribute_name|
42+
# self.public_send("#{attribute_name}=", attributes[
43+
# end
44+
# attributes.each do |attribute_name, value|
45+
# self.public_send("#{attribute_name}="
46+
#
47+
# end if attributes
48+
assign_attributes(attributes) if attributes
49+
@errors = ActiveModel::Errors.new(self)
50+
super()
51+
end
52+
53+
def attributes
54+
attribute_names.each_with_object({}) do |attribute_name, result|
55+
result[attribute_name] = public_send(attribute_name)
56+
end.with_indifferent_access
4257
end
4358

4459
# The following methods are needed to be minimally implemented for ActiveModel::Errors
@@ -51,5 +66,43 @@ def self.lookup_ancestors
5166
[self]
5267
end
5368
# :nocov:
69+
70+
def assign_attributes(new_attributes)
71+
unless new_attributes.respond_to?(:stringify_keys)
72+
fail ArgumentError, 'When assigning attributes, you must pass a hash as an argument.'
73+
end
74+
return if new_attributes.blank?
75+
76+
attributes = new_attributes.stringify_keys
77+
_assign_attributes(attributes)
78+
end
79+
80+
private
81+
82+
def _assign_attributes(attributes)
83+
attributes.each do |k, v|
84+
_assign_attribute(k, v)
85+
end
86+
end
87+
88+
def _assign_attribute(k, v)
89+
fail UnknownAttributeError.new(self, k) unless attribute_names.include?(k.to_sym) && respond_to?("#{k}=")
90+
public_send("#{k}=", v)
91+
end
92+
93+
def persisted?
94+
false
95+
end
96+
97+
# Raised when unknown attributes are supplied via mass assignment.
98+
class UnknownAttributeError < NoMethodError
99+
attr_reader :record, :attribute
100+
101+
def initialize(record, attribute)
102+
@record = record
103+
@attribute = attribute
104+
super("unknown attribute '#{attribute}' for #{@record.class}.")
105+
end
106+
end
54107
end
55108
end

test/action_controller/json_api/transform_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ module Serialization
55
class JsonApi
66
class KeyTransformTest < ActionController::TestCase
77
class KeyTransformTestController < ActionController::Base
8-
class Post < ::Model; end
9-
class Author < ::Model; end
10-
class TopComment < ::Model; end
8+
class Post < ::Model; attributes :title, :body, :author, :top_comments, :publish_at end
9+
class Author < ::Model; attributes :first_name, :last_name end
10+
class TopComment < ::Model; attributes :body, :author, :post end
1111
class PostSerializer < ActiveModel::Serializer
1212
type 'posts'
1313
attributes :title, :body, :publish_at

test/action_controller/namespace_lookup_test.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
module ActionController
44
module Serialization
55
class NamespaceLookupTest < ActionController::TestCase
6-
class Book < ::Model; end
7-
class Page < ::Model; end
8-
class Chapter < ::Model; end
9-
class Writer < ::Model; end
6+
class Book < ::Model; attributes :title, :body, :writer, :chapters end
7+
class Chapter < ::Model; attributes :title end
8+
class Writer < ::Model; attributes :name end
109

1110
module Api
1211
module V2

test/adapter/json_api/fields_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ module ActiveModelSerializers
44
module Adapter
55
class JsonApi
66
class FieldsTest < ActiveSupport::TestCase
7-
class Post < ::Model; end
8-
class Author < ::Model; end
9-
class Comment < ::Model; end
7+
class Post < ::Model; attributes :title, :body, :author, :comments end
8+
class Author < ::Model; attributes :name, :birthday end
9+
class Comment < ::Model; attributes :body, :author, :post end
1010

1111
class PostSerializer < ActiveModel::Serializer
1212
type 'posts'

test/adapter/json_api/include_data_if_sideloaded_test.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ class Serializer
55
module Adapter
66
class JsonApi
77
class IncludeParamTest < ActiveSupport::TestCase
8-
IncludeParamAuthor = Class.new(::Model)
8+
IncludeParamAuthor = Class.new(::Model) do
9+
attributes :tags, :posts
10+
end
911

1012
class CustomCommentLoader
1113
def all

test/adapter/json_api/linked_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
require 'test_helper'
22

3-
class NestedPost < ::Model; end
3+
class NestedPost < ::Model; attributes :nested_posts end
44
class NestedPostSerializer < ActiveModel::Serializer
55
has_many :nested_posts
66
end
@@ -301,8 +301,8 @@ def test_nil_link_with_specified_serializer
301301
end
302302

303303
class NoDuplicatesTest < ActiveSupport::TestCase
304-
class Post < ::Model; end
305-
class Author < ::Model; end
304+
class Post < ::Model; attributes :author end
305+
class Author < ::Model; attributes :posts, :roles, :bio end
306306

307307
class PostSerializer < ActiveModel::Serializer
308308
type 'posts'

test/adapter/json_api/links_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module ActiveModelSerializers
44
module Adapter
55
class JsonApi
66
class LinksTest < ActiveSupport::TestCase
7-
class LinkAuthor < ::Model; end
7+
class LinkAuthor < ::Model; attributes :posts end
88
class LinkAuthorSerializer < ActiveModel::Serializer
99
link :self do
1010
href "http://example.com/link_author/#{object.id}"

test/adapter/json_api/relationship_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ def build_serializer_and_serialize_relationship(model, relationship_name, &block
384384

385385
def new_model(model_attributes)
386386
Class.new(ActiveModelSerializers::Model) do
387-
attr_accessor(*model_attributes.keys)
387+
attributes(*model_attributes.keys)
388388

389389
def self.name
390390
'TestModel'

test/adapter/json_api/transform_test.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ module ActiveModelSerializers
44
module Adapter
55
class JsonApi
66
class KeyCaseTest < ActiveSupport::TestCase
7-
class Post < ::Model; end
8-
class Author < ::Model; end
9-
class Comment < ::Model; end
7+
class Post < ::Model; attributes :title, :body, :publish_at, :author, :comments end
8+
class Author < ::Model; attributes :first_name, :last_name end
9+
class Comment < ::Model; attributes :body, :author, :post end
1010

1111
class PostSerializer < ActiveModel::Serializer
1212
type 'posts'

test/cache_test.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class UncachedAuthor < Author
3434
end
3535

3636
class Article < ::Model
37+
attributes :title
3738
# To confirm error is raised when cache_key is not set and cache_key option not passed to cache
3839
undef_method :cache_key
3940
end

0 commit comments

Comments
 (0)