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

Easy filtering or specifying of additional fields #274

Closed
travisp opened this issue Jun 26, 2012 · 4 comments
Closed

Easy filtering or specifying of additional fields #274

travisp opened this issue Jun 26, 2012 · 4 comments
Labels

Comments

@travisp
Copy link

travisp commented Jun 26, 2012

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):

http://blog.apigee.com/detail/restful_api_design_can_your_api_give_developers_just_the_information/

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
     ....
  end
end

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

@databyte
Copy link
Collaborator

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.

@travisp
Copy link
Author

travisp commented Jun 26, 2012

@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.

@databyte
Copy link
Collaborator

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
  end

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

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

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.

@databyte
Copy link
Collaborator

If you have any other questions, just reopen.

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

No branches or pull requests

2 participants