Jsonapi-resources: Force relationship include

Created on 25 Feb 2016  路  9Comments  路  Source: cerebris/jsonapi-resources

Is there exist any way to force include relationship durning update a resource?
I have a case when I want to return, after update resource, all relationships that was changed by server.

Most helpful comment

In my case I was calling an association on the resource to populate an attribute which caused N+1 queries.

Using records_for_populate solved my problem.

The same example as @Ross-Hunter can be used:

class MyResource < JSONAPI::Resource
  def self.records_for_populate(options = {})
    super(options).includes(:comments)
  end
end

All 9 comments

@Exelord

If you submit

PUT /articles/1?include=comments

the comments are included in the response JSON, aren't they?

Yes but I want to include all relationship of fresh created object automatically. Is the include only one option for do that?

The only way I can think of is modifying include in controller

class ArticlesController < ActionController::Base
  include JSONAPI::ActsAsResourceController

  def create
    params[:include].to_s.concat(',comments')
    super
  end
end

Yep I done like that but I think I need to do that on the resource level. Sometimes I make a lot of operations eg in case of update or create some resource on that level and I need to force include some relationships to inform front end that something change what it doesn't request.

Eg. I need to change one relationship to default value after updating another one. And the problem is during returning them. It's not possible to do from resource :/

class MyResource < JSONAPI::Resource
  class << self
    def apply_includes(records, directives)
      super.includes(:comments)
    end
  end
end

Will always apply include active record relationship by default. Or i got it wrong?

@Fedcomp if I understand correctly, you're trying to configure the resource to include(side load) relationships by default? The code you posted is for eager loading relationships for performance reasons and will not affect the API response.

Check out #389 for more discussion on this

If you want to include resources for performance reasons, not display purposes. (this thread ranks highly for these keywords)

class MyResource < JSONAPI::Resource
  def self.records(options = {})
    super(options).includes(:comments)
  end
end

I think some of the internals have been moved around and apply_includes did not do anything for me.

In my case I was calling an association on the resource to populate an attribute which caused N+1 queries.

Using records_for_populate solved my problem.

The same example as @Ross-Hunter can be used:

class MyResource < JSONAPI::Resource
  def self.records_for_populate(options = {})
    super(options).includes(:comments)
  end
end

You can force an include in a resource by directly adding it to the include_directives. The include directives object can be found in the options of many resource methods such as find_fragments. For me, I put the include directives into the context in my base controller before any operation processing so I can access it anywhere. With that you can do this in your resource:

context[:include_directives].include_directives[:include_related][:some_entity] = { include_related: {} }
Was this page helpful?
0 / 5 - 0 ratings