Renderizando un simple hash de Ruby con RABL
rendering (7)
Tengo un hash de rubí que me gustaría renderizar usando RABL . El hash se ve algo como esto:
@my_hash = {
:c => {
:d => "e"
}
}
Estoy tratando de renderizar esto con un código RABL:
object @my_hash => :some_object
attributes :d
node(:c) { |n| n[:d] }
pero estoy recibiendo {"c":null}
¿Cómo puedo hacer esto con RABL?
A veces es fácil hacer demasiado imho.
Que tal solo
render json: my_hash
Y al igual que la magia podemos borrar algún código!
Actualmente RABL no juega muy bien con hashes. Pude evitar esto al convertir mi hash a un formato OpenStruct (que utiliza una notación de puntos más compatible con RABL). Usando tu ejemplo:
your_controller.rb
require ''ostruct''
@my_hash = OpenStruct.new
@my_hash.d = ''e''
tu_vista.rabl
object false
child @my_hash => :c do
attributes :d
end
resultados
{
"c":{
"d":"e"
}
}
Al especificar un nodo como ese, se le otorga acceso al objeto @my_hash
cual puede acceder a los atributos de. Así que solo cambiaría un poco tu código para ser:
object @my_hash
node(:c) do |c_node|
{:d => c_node.d}
end
donde c_node
es esencialmente el objeto @my_hash
. Esto debería darle lo que está esperando (que se muestra aquí en JSON):
{
"my_hash":{
"c":{
"d":"e"
}
}
}
Esto funciona para valores hash arbitrarios.
object false
@values.keys.each do |key|
node(key){ @values[key] }
end
Me funcionó con Rails 3.2.13 y Ruby 2.0.0-p195
Mi respuesta se basa parcialmente en el siguiente sitio:
Adaptado de este sitio:
http://www.rubyquiz.com/quiz81.html
require "ostruct"
class Object
def to_openstruct
self
end
end
class Array
def to_openstruct
map{ |el| el.to_openstruct }
end
end
class Hash
def to_openstruct
mapped = {}
each{ |key,value| mapped[key] = value.to_openstruct }
OpenStruct.new(mapped)
end
end
Defina esto tal vez en un inicializador y luego, para cualquier hash, simplemente póngalo en oprimir y envíelo a la plantilla de rabl y, básicamente, haga lo que jnunn muestra en la vista.
RABL puede procesar hashes y arreglos de rubí fácilmente, como atributos, pero no como objeto raíz. Entonces, por ejemplo, si creas un OpenStruct como este para el objeto raíz:
@my_object = OpenStruct.new
@my_object.data = {:c => {:d => ''e''}}
Entonces podrías usar esta plantilla RABL:
object @my_object
attributes :data
Y eso haría que:
{"data": {"c":{"d":"e"}} }
Alternativamente, si desea que :c
sea una propiedad de su objeto raíz, puede usar "nodo" para crear ese nodo y generar el hash dentro de ese nodo:
# -- rails controller or whatever --
@my_hash = {:c => {:d => :e}}
# -- RABL file --
object @my_hash
# Create a node with a block which receives @my_hash as an argument:
node { |my_hash|
# The hash returned from this unnamed node will be merged into the parent, so we
# just return the hash we want to be represented in the root of the response.
# RABL will render anything inside this hash as JSON (nested hashes, arrays, etc)
# Note: we could also return a new hash of specific keys and values if we didn''t
# want the whole hash
my_hash
end
# renders:
{"c": {"d": "e"}}
Por cierto, esto es exactamente lo mismo que usar render :json => @my_hash
en los rieles, por lo que RABL no es particularmente útil en este caso trivial;) Pero de todos modos demuestra la mecánica.
RABL se ocupa de los objetos, pero no requiere un ORM en particular. Solo objetos que soportan la notación de puntos. Si quieres usar rabl y todo lo que tienes es un hash:
@user = { :name => "Bob", :age => 27, :year => 1976 }
luego, primero debe convertir el hash en un objeto que admita la notación de puntos:
@user = OpenStruct.new({ :name => "Bob", :age => 27, :year => 1976 })
y luego dentro de una plantilla RABL, trate el OpenStruct como cualquier otro objeto:
object @user
attributes :name, :age, :year
Tenga en cuenta que si todo lo que está haciendo en su aplicación solo trata con hashes y no hay objetos o bases de datos involucrados, es posible que esté mejor con un generador de JSON más personalizado como json_builder o jbuilder.
Pegado desde la página wiki oficial en github de RABL: github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl