Skip to content
haxney edited this page Aug 22, 2011 · 12 revisions

How to output some random, not directly related items:

Say you want to return a few things, for example a proper data item, and also a status code and message. You don't want to create an object just to hold these items for the output view, but instead just use them all directly in the output view. To do this, make the objects instance variables, like usual, eg:

@foo = "bar"
@pop = 123

Then use the "object false" facility in the RABL template, like so:

object false
node(:foo) { @foo }
node(:pop) { @pop }

If @foo is a more complex object, you can just specify which of its attributes to use by using a child() call instead, like this:

model:

class Car
  attr_accessor :car_make, :car_name
end

controller:

@cars = Car.all
@status = "ok"

view:

object false
child(@cars) { attributes :car_name, :car_make }
node(:status) { @status }

output (assuming json roots are turned off):

{ status:"ok", [{ car_make:"Toyota", car_name:"Prius"},...]}

How to use any object for the view, not just ORM specific ones:

You want to use a non-ORM object in the view, but just using any old does not quite work with RABL (at least for now), but if acceptable a few tweaks to your object can make it RABL friendly.

class Thing < Struct.new(:foo, :pop)
   def initialize(h)
     super *h.values_at(*self.class.members.map {|s| s.intern})
   end

  def valid?; true; end
end

Which can then be used like so in the controller:

@thing2 = Thing.new(:foo => "boo", :pop => 987)

And as a usual object in the view:

object @thing2
attributes :foo, :pop

For an object to be RABL-friendly, it needs to have each attribute available as an instance method. RABL expects MyObject#respond_to? to return true for each specified attribute.