Easy filtering or specifying of additional fields #274

travisp opened this Issue Jun 26, 2012 · 4 comments

2 participants


Sometimes when designing an API, it's good to give clients the ability to specify a more limited set of fields to return (e.g. Google, LinkedIn, Facebook) , or allow specifying additional fields (e.g. Bugzilla):


It would be great if something like this could be built into rabl so that rabl could just skip attributes that were not specified somewhere instead of something like:

object @user
if @fields.nil? || @fields["lists"]
  child :lists do

Any thoughts on this, or is there a good way to do this now?


Check out some of the examples on the wiki under Referencing objects in extended views

That should get you one step closer.

An approach that I like is to use a node and place some logic in there to optionally call partial. Which happens to be the last example on the page above.


@databyte, conditionally calling a partial could help some, but it would be nice to make returning any attribute optional when the optional "fields" parameter is passed. As is, attempting to implement this design makes the views very messy since each attribute would require its own conditional check.


Attributes that don't exist are optional. In other words, if you had two objects like Kitten and Tiger which both have name and cuteness_level but only Bar has the attribute will_kill_you.

object @cat

attributes :name, :cuteness_level, :will_kill_you

Then if you pass it either object, RABL will output it for you ignoring :will_kill_you for the objects that don't have it.

The way I would do optional conditional checks on when to display or not to display attributes wouldn't be in the view (which is RABL) but in an object itself.

Create a new composite object, use the Presenter pattern, or the Decorator pattern. See Draper for decorator and display_case for an "Exhibit" pattern (where decorators and presentation patterns were get'n it on).

A simple presentation object could be:

class UserWithList
  def initialize(user)
    @user = user

  def fields
    [:name, :created_at, :lists]

  def method_missing(method, *args)
    args.empty? ? @user.send(method) : @user.send(method, args)

Then your template would be something like:

object UserWithList.new(@user)
attributes *fields

Of course I typed that all out and there's most likely a typo somewhere. You can also use a cleaner DRY-er DSL with SimpleDelegator or Draper.


If you have any other questions, just reopen.

@databyte databyte closed this Jul 11, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment