cerebris / jsonapi-resources

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

Can you load a specific attribute on a certain request? #725

Closed iamajvillalobos closed 8 years ago

iamajvillalobos commented 8 years ago

So I got this scenario that I wanted to load an attribute :output, if the resource requested a POST request. This output method does is connect to an external api and gives back result, but when I do a GET request I don't want it to run. Is there a different approach to this problem than my current solution? It seems I can't find the answer :). Any help/thoughts?

lgebhardt commented 8 years ago

There isn't an out of the box solution. However you could add an attribute to your resource as you are showing, and then prohibit that field for every request but the ones you want using the fetchable_fields method. For example:

class AuthorResource < JSONAPI::Resource
  def fetchable_fields
    if context[:has_output]
      super 
    else 
      super - [:output]
    end
  end
end

You could set the context[:has_output] in your controller based on the action. You could also store the action in the context to reference later.

I haven't tested this, but it should work.

iamajvillalobos commented 8 years ago

Hey @lgebhardt thanks! I got this code now:

  attributes :name, :output

  def fetchable_fields
    unless (context[:request_method] == "POST")
      super - [:output]
    end
  end

  def output
    ["hello"]
  end

But I'm getting error of:

Internal Server Error: undefined method `each_with_object' for false:FalseClass /Users/ajvillalobos/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/jsonapi-resources-0.7.0/lib/jsonapi/resource_serializer.rb:154:in `attribute_hash'

I wonder what's wrong?

iamajvillalobos commented 8 years ago

Ops! never mind, I forgot to add super as a default case. Thanks @lgebhardt!