-
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
Smarter association id lookup-- no db hit on belongs_to for id-only #1857
Conversation
@bf4, thanks for your PR! By analyzing the annotation information on this pull request, we identified @beauby, @ehsanyousefi and @bolshakov to be potential reviewers |
Do you plan to fix the bug, or is this just to demonstrate the problem? (either is cool) |
3abc80b
to
c93e599
Compare
c93e599
to
cb515f8
Compare
reflection_options[:include_data] = @_include_data | ||
reflection_options[:new_options] = { |
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.
hack to allow for refactoring...
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.
I was just about to ask about this, thanks
cb515f8
to
282ac72
Compare
I think I got it working and all tests passing! Now time for review. |
# parent_serializer = AuthorSerializer.new(@author) | ||
# relationship = Relationship.new(parent_serializer, @serializer, nil, params) | ||
# assert_equal(expected, relationship.as_json) | ||
# 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.
These tests, like much of the JSONAPI code, are tightly coupled to the implementation.
They are asserting a relationship between two serializers that are not necessarily actually related.
The impl in this PR is to pass in the parent serializer and the association.
In these tests, the association would need to be derived from the @serializer
. I couldn't get this the api to this test file right, so am relying on the remainder of the test suite.
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.
(DO NOT merge with this commented out... tbd what to do about it)
(Test failure right now are regularly occurring but intermittent... tests pass though, and pr needs refactoring, so this is a good chance to look) |
@bf4 this is a great feature! Regarding "This will only work on active record objects", would it be possible to define an interface (+ default handling for ActiveRecord) such that other ORMs can use it too (or use some other mechanism, basically anything that'll make this useful for other ORMs that are similar to ActiveRecord). For example Mongoid. |
Well, I wrote it using respond_to, so if it quacks that way it will work. I'm not familiar with the interface needed by mongoid B mobile phone
|
@@ -2,6 +2,12 @@ module ActiveModel | |||
class Serializer | |||
# @api private | |||
class CollectionReflection < Reflection | |||
def initialize(*) | |||
super | |||
@class_name = options.fetch(:class_name, name.to_s.camelize.singularize) |
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.
should these maybe be methods?
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.
as oppose to in the initializer?
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.
I'm just wary of too much logic in an initializer / any method
options[:new_options] = { | ||
meta: test_options.delete(:meta), | ||
links: test_options.delete(:links), | ||
reflection: parent_serializer._reflections.to_a.first |
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.
I know this is broken (in the rebase off of master), but just wanted to push the work for the moment
32dbfa9
to
93fa05b
Compare
@serializable_resource_options = {} # adapter.instance_options | ||
end | ||
|
||
def build_author_relationship(author_attributes, association_name) |
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.
I completely rewrote the test harness and assertion in this file.. could use a second pair of eyes, but at least I think it is straightforward enough to read the assertions and understand, and to read the harness and understand what it's doing (even if not so clear why it's so complicated, and how could it be simpler).
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.
I think it's pretty straight forward, usage wise.
though, why do you need to reset the reflection stuff?
is that for isolation or something else?
my concern is that if something is happening to those normally that is being avoided here, it could reveal a hole in testing.
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.
Just that normally these are created by the serializer using these as defaults in the reflection initializer, but here I am mutating them, which changes them for all the tests, and dup and deep_dup didn't work. So it's a hack to make the serializer behave in each test as if it were being defined for the first time.
B mobile phone
On Aug 18, 2016, at 6:53 AM, L. Preston Sego III notifications@github.com wrote:
In test/adapter/json_api/relationship_test.rb:
setup do
@blog = Blog.new(id: 1)
@author = Author.new(id: 1, name: 'Steve K.', blog: @blog)
@serializer = BlogSerializer.new(@blog)
ActionController::Base.cache_store.clear
@serializable_resource_options = {} # adapter.instance_options
end
I think it's pretty straight forward, usage wise.def build_author_relationship(author_attributes, association_name)
though, why do you need to reset the reflection stuff?
is that for isolation or something else?
my concern is that if something is happening to those normally that is being avoided here, it could reveal a hole in testing.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
ce5c4b8
to
919380e
Compare
I just rebased and broke a lot of stuff... I'll need to review the diff for what changes we actually want at this point. So, yes, lots of failures now that need to be addressed, it is known. |
ce5c4b8
to
919380e
Compare
ce5c4b8
to
6e41528
Compare
@bf4 Hey, thank you for this improvement. Examle: serializer: class CommentSerializer < ActiveModel::Serializer
# ....
belongs_to :commentable
end request: result: //...
"relationships": {
"commentable": {
"data": {
"id": "1",
"type": "commentables"
}
}
}
//... Can you check it out? |
def initialize(*) | ||
super | ||
options[:links] = {} | ||
options[:include_data_setting] = Serializer.config.include_data_default | ||
options[:meta] = nil | ||
@type = options.fetch(:type) do | ||
class_name = options.fetch(:class_name, name.to_s.camelize.singularize) |
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.
This line is causing the bug reported here: #2160 In particular, the use of the field's name
if the class_name
and type
aren't specified breaks belongs_to associations.
If the serializer has an association,
The thing where it doesn't actually call the association is a
special case where AMS needs to know it can get the relationship id
from the resource itself, so that userland code doesn't need to do any fancy association preloading.
The way this has been solved in JSONAPI-Resources
is to have special rules for looking up association ids.
And see JSONAPI::Relationship
In brief:
has_many :authors
:author_ids
has_one :author
:author_id
belongs_to :author
:author_id
Caveat:
This will only work on active record objects
Includes:
Follows:
Related: