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:
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.
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:
@user = user
[: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:
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.