Skip to content
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

Using include_<association>? in 0.10.x not working? #857

Closed
jensbjork opened this issue Mar 24, 2015 · 12 comments
Closed

Using include_<association>? in 0.10.x not working? #857

jensbjork opened this issue Mar 24, 2015 · 12 comments

Comments

@jensbjork
Copy link

In a nutshell, I have the following scenario:

Controller:

def index
    associations = params[:include] ? params[:include].split(",").map { |v| v.to_sym } : nil
    @posts = @posts.includes(associations)

    if @posts
        render json: @posts, include: params[:include]
    else
        render nothing: true, status: 404
    end
end

Serializer:

class PostSerializer < ActiveModel::Serializer
    attributes :id, :title
    has_many :comments

    def include_comments?
        object.association(:comments).loaded?
    end
end

My goal is to only load and query the database if associations are included in the include get parameter as of the JSON API standard. It seems like the include_association? is not handled at all, I've tried to return false directly in the method, but the assocations still queries the database. E.g:

def include_comments?
    false
end

I can't seem find documentation for this. Has the method changed or is there any other preferred way of doing this?

I am using master branch (0.10.x) and the JSON API adapter.

Thanks in advance

@rowlandrudolf
Copy link

Ran into the same situation... If you don't mind having an empty array you can redefine the :comments

has_many :comments

def comments
  object.association(:comments).loaded? ? object.comments : [] 
end

Or override the associations method.. Pretty ugly solution but it works as your include_comments? would

def included_associations
  [ :comments ] #etc..
end

def associations
  object_associations = super
  included_associations.each do |assoc|
    next unless object.association(assoc).loaded?
    object_associations[assoc] = []
    object.public_send(assoc).map { |c| object_associations[assoc] << get_serializer(c).as_json }
  end
  object_associations
end

def get_serializer(object, root=false)
  "#{object.class}Serializer".constantize.new(object, root: root)
end

@scttnlsn
Copy link

Is support for include_<attr or association>? planned for 0.10.x? I'd be happy to put together a pull request with this functionality (based on the 0.8.x code).

@joaomdmoura joaomdmoura added this to the 0.10 milestone May 18, 2015
@ryansch
Copy link
Contributor

ryansch commented May 18, 2015

I've hit my head on this as well.

@joaomdmoura joaomdmoura self-assigned this May 18, 2015
@scttnlsn
Copy link

Here's a simple implementation that I'm trying out at the moment: master...scttnlsn:inclusion

@joaomdmoura
Copy link
Member

I haven't read the thread yet, but it's already in my radar.
@scttnlsn make yourself comfortable, I can't guarantee that we will merge it, because as I said, I haven't read it yet. But thank you for your help and keep it up! 👍

@lukebergen
Copy link

Confirmed that this is also an issue (at least for me) in 0.9.3.

Edit: reading http://stackoverflow.com/questions/23390678/active-model-serializer-conditional-associations, I get the impression that 0.9.x changed things to use "filter" instead so nevermind. I guess I shouldn't have been using include_[attribute]? in 0.9.x to begin with. But for clarification, it will be coming back in 0.10.x? I don't see anything about filter in the 0.10.x readme.

@joaomdmoura
Copy link
Member

ppl, just a quick update, we have being talking about conditional attributes, and we decided that filter will probably be coming back in 0.10.x cc/@lukebergen

We haven't started it yet because we are busy into some new features to AMS too, but we are willing to review a PR implementing it, otherwise it's already on our todo-list to a near-future. For now I'm closing this PR.

@leonelgalan
Copy link
Contributor

Yeah, include_[attribute]? was dropped sometime around 0.9.0 (CHANGELOG.md change and Implentation commit) in favor of filter. I'm glad to know filter is coming back!

@dpmccabe
Copy link

I wanted to customize both the attributes and the associations according to some_flag (where if true then only a few of the attributes and one particular association are included) and this is how I solved it:

belongs_to :user
belongs_to :bill_address
belongs_to :stripe_card
has_many :shipments

def attributes(options = {})
  if object.some_flag
    super.slice(*%i(number state email errors))
  else
    super
  end
end

def each_association(&block)
  self.class._associations.dup.each do |name, association_options|
    next unless object && included_associations.include?(name)

    association_value = send(name)

    serializer_class = ActiveModel::Serializer.serializer_for(association_value, association_options)

    serializer = serializer_class.new(
      association_value,
      options.merge(serializer_from_options(association_options))
    ) if serializer_class

    if block_given?
      block.call(name, serializer, association_options[:association_options])
    end
  end
end

def included_associations
  if object.some_flag
    %i(bill_address)
  else
    %i(user bill_address stripe_card shipments)
  end
end

@joaomdmoura
Copy link
Member

@dpmccabe would be awesome if you could checkout #999 and give it try. Check if it solves your problema, if it does 👍 it. 😄

@sars
Copy link

sars commented Mar 1, 2016

Guys, any updates on this issue?

@bf4
Copy link
Member

bf4 commented Mar 1, 2016

@sars Are you asking about conditional attributes? If so, they're implemented in master. If you're asking about the specific syntax, it is not planned at present to re-introduce it, except, perhaps, in a 'legacy' serializer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests