-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix AMS::Model accessor vs. attributes mutation #1903
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ module ActiveModelSerializers | |
class ModelTest < ActiveSupport::TestCase | ||
include ActiveModel::Serializer::Lint::Tests | ||
|
||
def setup | ||
setup do | ||
@resource = ActiveModelSerializers::Model.new | ||
end | ||
|
||
|
@@ -18,5 +18,46 @@ def test_initialization_with_string_keys | |
|
||
assert_equal model_instance.read_attribute_for_serialization(:key), value | ||
end | ||
|
||
def test_attributes_can_be_read_for_serialization | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this test is about a change via accessor instead of constructor. Maybe the test name could be a little more descriptive in that regard? |
||
klass = Class.new(ActiveModelSerializers::Model) do | ||
attr_accessor :one, :two, :three | ||
end | ||
original_attributes = { one: 1, two: 2, three: 3 } | ||
instance = klass.new(original_attributes) | ||
|
||
# Initial value | ||
expected_attributes = { one: 1, two: 2, three: 3 } | ||
assert_equal expected_attributes, instance.attributes | ||
assert_equal 1, instance.one | ||
assert_equal 1, instance.read_attribute_for_serialization(:one) | ||
|
||
# Change via accessor | ||
instance.one = :not_one | ||
|
||
assert_equal :not_one, instance.one | ||
assert_equal :not_one, instance.read_attribute_for_serialization(:one) | ||
end | ||
|
||
def test_id_attribute_can_be_read_for_serialization | ||
klass = Class.new(ActiveModelSerializers::Model) do | ||
attr_accessor :id, :one, :two, :three | ||
end | ||
self.class.const_set(:SomeTestModel, klass) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? |
||
original_attributes = { id: :ego, one: 1, two: 2, three: 3 } | ||
instance = klass.new(original_attributes) | ||
|
||
# Initial value | ||
assert_equal 1, instance.one | ||
assert_equal 1, instance.read_attribute_for_serialization(:one) | ||
|
||
# Change via accessor | ||
instance.id = :superego | ||
|
||
assert_equal :superego, instance.id | ||
assert_equal :superego, instance.read_attribute_for_serialization(:id) | ||
ensure | ||
self.class.send(:remove_const, :SomeTestModel) | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'm not totally sure this would work. You'd get into this scenario:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's true. I think that's just another point for the current AMS::Model being broken. :-(
Do you have a PR for your module idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, I was waiting to get approval of the RFC. Because what would that module be? Would it contain the constructor logic (in which case we are in the business of overriding the superclass's constructor which is gross)? And if not, what would it include?
As far as I can tell it would just be
alias read_attribute_for_serialization send
, and in that case I'm not sure what the point of it is.So, TBH AMS::Model is nonsensical to me, which means I don't think I can touch the code or enhance the documentation in a meaningful way. I created the RFC to try and improve that situation, but doesn't look like it is getting any traction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW you can fix the current class with something like this and this. That got the tests passing, including the scenario above, though it's just POC code.