ruby-on-railsjsonapiruby-on-rails-4rocketpants

Reference a method (with argument) in the Rocket Pants collection response?


Using the Rocket Pants gem for an API, I'm wanting to be able to return a custom value in the collection json. For example, I'm currently doing this:

collection(
  current_user.prizes,
  include: { location: { only: [:title] } },
  only: [:last_prize_at]
)

This returns a JSON response like the following:

{
  "response": [
    {
      "location": {
        "title": "My name"
      },
      "last_prize_at": "10-10-15"
    }
  ],
  "count": 1
}

This is pretty straight-forward and is working as it should.

What I'm wanting to do is reference a method with an argument in the response, for example:

# current_user has a method called "prizes_from(location_id)"
collection(
  current_user.prizes,
  include: { location: { only: [:title] } },
  only: [:last_prize_at],
  prize_list: current_user.prizes_from(:location_id)   # < this line doesn't work
)

The code above obviously does not work, however, it shows what I'm trying to do. Here is an example response of what it should look like:

{
  "response": [
    {
      "location": {
        "title": "My name"
      },
      "last_prize_at": "10-10-15",
      "prize_list": [                # < here
        { .... }
      ]           
    }
  ],
  "count": 1
}

How can I achieve this?


Solution

  • The methods option was what I was looking for:

    collection(
      current_user.prizes,
      include: { location: { only: [:title] } },
      only: [:last_prize_at],
      methods: [:user_prize_list]        # Added line here
    )
    

    Unfortunately, I've not found a way to be able to access sub-methods directly, or how to use arguments. So to make the code above functional, I had to add this to my Location model:

    def user_prize_list(location=nil, user=nil)
      location ||= self
      user ||= location.user
      user.prizes_from(location.id)
    end
    

    It works though!