Рендеринг простого хэша Ruby с помощью RABL - PullRequest
19 голосов
/ 20 января 2012

У меня есть хэш ruby, который я хотел бы отрендерить, используя RABL . Хеш выглядит примерно так:

@my_hash = {
    :c => {
        :d => "e"
    }
}

Я пытаюсь сделать это с помощью кода RABL:

object @my_hash => :some_object
attributes :d
node(:c) { |n| n[:d] }

но я получаю {"c":null}

Как я могу сделать это с RABL?

Ответы [ 7 ]

30 голосов
/ 28 июня 2013

Это работает для произвольных значений хеш-функции.

object false

@values.keys.each do |key|
  node(key){ @values[key] }
end

Работало для меня, используя Rails 3.2.13 и Ruby 2.0.0-p195

22 голосов
/ 22 марта 2012

В настоящее время 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"
  }
}
6 голосов
/ 07 марта 2013

Иногда легко сделать слишком много imho.

Как насчет просто

render json: my_hash

И, как по волшебству, мы можем удалить некоторый код!

5 голосов
/ 04 мая 2014

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.

Вставлено с официальной вики-страницы на github RABL: https://github.com/nesquena/rabl/wiki/Rendering-hash-objects-in-rabl

4 голосов
/ 04 февраля 2013

RABL на самом деле может легко отображать хэши и массивы ruby ​​как атрибуты, но не как корневой объект.Так, например, если вы создадите OpenStruct для корневого объекта, подобный этому:

@my_object = OpenStruct.new
@my_object.data = {:c => {:d => 'e'}}

Тогда вы можете использовать этот шаблон RABL:

object @my_object

attributes :data

И это будет отображать:*

{"data": {"c":{"d":"e"}} }

В качестве альтернативы, если вы хотите, чтобы :c было свойством корневого объекта, вы можете использовать "узел" для создания этого узла и визуализации хеша внутри этого узла:

# -- 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 не особенно полезен в этом тривиальном случае;) Но в любом случае он демонстрирует механику.

2 голосов
/ 21 сентября 2012

Мой ответ частично основан на приведенном ниже сайте:

Адаптировано с этого сайта:

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 показывает в представлении.

2 голосов
/ 20 января 2012

Указав такой узел, вы получаете доступ к объекту @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"
      }
   }
}
...