Подтвердить что ты не робот

Предоставление простого хэша Ruby с RABL

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

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

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

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

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

Как это сделать с помощью RABL?

4b9b3361

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