Предоставление простого хэша Ruby с RABL
У меня есть хэш-рубин, который я бы хотел сделать с помощью RABL. Хэш выглядит примерно так:
@my_hash = {
:c => {
:d => "e"
}
}
Я пытаюсь сделать это с помощью некоторого кода RABL:
object @my_hash => :some_object
attributes :d
node(:c) { |n| n[:d] }
но я получаю {"c":null}
Как это сделать с помощью RABL?
Ответы
Ответ 1
В настоящее время RABL не слишком хорошо играет с хешами. Я смог обойти это, преобразовывая свой хеш в формат OpenStruct (который использует более точную нотацию RABL). Используя ваш пример:
your_controller.rb
require 'ostruct'
@my_hash = OpenStruct.new
@my_hash.d = 'e'
your_view.rabl
object false
child @my_hash => :c do
attributes :d
end
Результаты
{
"c":{
"d":"e"
}
}
Ответ 2
Это работает для произвольных хеш-значений.
object false
@values.keys.each do |key|
node(key){ @values[key] }
end
Работала для меня с помощью Rails 3.2.13 и Ruby 2.0.0-p195
Ответ 3
Иногда его легко сделать слишком много imho.
Как насчет просто
render json: my_hash
И точно так же, как магия, мы можем удалить код!
Ответ 4
RABL обрабатывает объекты, но не требует определенного ORM. Просто объекты, которые поддерживают точечную нотацию. Если вы хотите использовать rabl, и все, что у вас есть, это хэш:
@user = { :name => "Bob", :age => 27, :year => 1976 }
тогда вам нужно сначала превратить хеш в объект, который поддерживает точечную нотацию:
@user = OpenStruct.new({ :name => "Bob", :age => 27, :year => 1976 })
а затем в шаблоне RABL обработайте OpenStruct как любой другой объект:
object @user
attributes :name, :age, :year
Учтите, что если все, что вы делаете в своем приложении, просто имеет дело с хэшами, и нет объектов или баз данных, вам может быть лучше с альтернативным более настраиваемым JSON-конструктором, таким как json_builder или jbuilder.
Вставка с официальной вики-страницы в RABL github: https://github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl
Ответ 5
RABL на самом деле может легко отображать рубиновые хэши и массивы как атрибуты, а не как корневой объект. Так, например, если вы создаете OpenStruct, как это для корневого объекта:
@my_object = OpenStruct.new
@my_object.data = {:c => {:d => 'e'}}
Затем вы можете использовать этот шаблон RABL:
object @my_object
attributes :data
И это сделает:
{"data": {"c":{"d":"e"}} }
В качестве альтернативы, если вы хотите, чтобы :c
являлся свойством вашего корневого объекта, вы можете использовать "node" для создания этого node и визуализировать хэш внутри node:
# -- 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"}}
Кстати, это точно так же, как просто использование render :json => @my_hash
в рельсах, поэтому RABL не особенно полезен в этом тривиальном случае;) Но он все равно демонстрирует механику.
Ответ 6
Указав такой node, вам предоставляется доступ к объекту @my_hash
, к которому вы можете получить доступ к атрибутам. Поэтому я бы слегка изменил ваш код:
object @my_hash
node(:c) do |c_node|
{:d => c_node.d}
end
где c_node
по существу является объектом @my_hash
. Это должно дать вам то, что вы ожидаете (показано здесь в JSON):
{
"my_hash":{
"c":{
"d":"e"
}
}
}
Ответ 7
Мой ответ частично основан на приведенном ниже сайте:
Адаптировано с этого сайта:
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
Определите это, возможно, в инициализаторе, а затем для любого хеша просто поместите to_openstruct и отправьте это на шаблон rabl и в основном выполните то, что jnunn показывает в представлении.