cerebris / jsonapi-resources

A resource-focused Rails library for developing JSON:API compliant servers.
http://jsonapi-resources.com
MIT License
2.32k stars 530 forks source link

Included resource choosing wrong Arel table #1127

Open adambedford opened 6 years ago

adambedford commented 6 years ago

I'm running into an issue where including one resource (user) ends up using another Arel table (account), and thus the include blows up with Internal Server Error: key not found: 11. 11 is the Account ID of the user, but the user ID is 68, which is specified on the parent resource as user_id.

I've stepped through the code a bit to determine that pluck_attrs in JSONAPI::Resource#preload_include_fragments has the wrong Arel::Table but I'm not sure what the cause of that is.

My models and resources are configured in a very straightforward manner:

JobApplication < ApplicationRecord
  belongs_to :user, inverse_of: :job_applications, touch: true, counter_cache: true
end

User < ApplicationRecord
  has_many :job_applications, inverse_of: :user, dependent: :destroy
end

Any idea why this would be happening?

adambedford commented 6 years ago

I don't know what the solution here is yet, but I think this is due to the fact that the original relation already joins in user and account. The relation SQL looks like this:

SELECT "job_applications".* FROM "job_applications" 
  INNER JOIN "users" ON "users"."id" = "job_applications"."user_id" 
  INNER JOIN "account_memberships" ON "account_memberships"."user_id" = "users"."id" 
                                      AND "account_memberships"."deactivated_at" IS NULL 
  INNER JOIN "accounts" ON "accounts"."id" = "account_memberships"."account_id" 
WHERE "job_applications"."user_id" = 67 
      AND "accounts"."id" = 11 
      AND "job_applications"."id" IN (504, 505, 506, 507, 508, 509)
senid231 commented 6 years ago

@adambedford can you add more details?

I mean request URL that server receives, models and resources for job_applications, users and accounts

lgebhardt commented 6 years ago

@adambedford Which version of JR are you running? Would it be possible for you to reproduce this using the bug report template?

blindMoe commented 6 years ago

@adambedford Did you make any headway with this? I am running into a similar situation

adambedford commented 6 years ago

@blindMoe I ended up using a subquery rather than joining in the tables that were causing issues

Subtletree commented 6 years ago

I'm seeing this too in 0.9.1.beta1 with caching enabled. The problem does not occur with caching disabled.

Seems to happen when a record is included through more than one path e.g

# Nothing special going on with models
User
  has_many :posts
  has_many :comments

Post
  has_many :comments
  belongs_to :user

Comment
  belongs_to :post
  belongs_to :user
user
  id: 1

post
  id: 1
  user_id: 1

comment
  id: 1
  post_id: 1
  user_id: 1

GET users/1?include=posts.comments,comments

comment (id: 1) is included in both post.comments and user.comments


Internal Server Error: key not found: KEY_NUMBER_IS_HERE

jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1241:in `fetch'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1241:in `block (3 levels) in preload_included_fragments'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1236:in `each'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1236:in `each_with_index'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1236:in `block (2 levels) in preload_included_fragments'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1234:in `each'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1234:in `block in preload_included_fragments'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1146:in `each'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1146:in `preload_included_fragments'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:1078:in `cached_resources_for'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:782:in `find_serialized_with_caching'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/resource.rb:795:in `find_by_key_serialized_with_caching'
jsonapi-resources-0.9.1.beta1/lib/jsonapi/processor.rb:123:in `show'