RABL - Визуализация коллекции как объекта с идентификаторами в качестве ключей
В Ruby on Rails 4 я пытаюсь создать API для своего сайта, а не использовать массив следующим образом:
[{id: 1, name: "John"}, {id: 2, name: "Foo"}, {id: 3, name: "Bar"}]
Я хочу сделать это так, потому что это облегчает поиск в javascript (и по другим причинам):
{"1": {id: 1, name: "John"}, "2": {id: 2, name: "Foo"}, "3": {id: 3, name: "Bar"}}
Это работает:
# users/index.rabl
@users.each do |user|
node(users.id.to_s) do
partial('api/v1/users/show', object: user)
end
end
Но в частичном, я хочу другую коллекцию элементов (которые принадлежат пользователю), и я не могу заставить это работать. Есть ли более элегантный способ сделать это?
1 ответ
Выбор хэш-карты, а не массива, безусловно, лучший вариант, если у вас есть контроль над кодовой базой API-интерфейса. Из нотации BigO поиск хеша происходит с постоянным временем O(1), а не O(n), как для массива.
Поиск первичного ключа из базы данных является наиболее эффективным способом запроса данных. Первичный ключ обычно короткий и всегда индексируется. В случае большого набора данных используйте нумерацию страниц.
Давайте предположим, что RABL отсутствует (вы всегда можете создать чистые классы Ruby в коде RABL DSL), а просто массив:
array = [{id: 1, name: "John"}, {id: 2, name: "Foo"}, {id: 3, name: "Bar"}]
hash = {}
array.each{ |elem,i| hash[elem[:id].to_s] = elem }
# {"1"=>{:id=>1, :name=>"John"}, "2"=>{:id=>2, :name=>"Foo"}, "3"=>{:id=>3, :name=>"Bar"}}
Чтобы передать хеш Ruby в Javascript на клиенте, вы, вероятно, захотите закодировать его соответствующим образом:
# hash.to_json
# {"1":{"id":1,"name":"John"},"2":{"id":2,"name":"Foo"},"3":{"id":3,"name":"Bar"}}
Из Javascript вы запрашиваете хеш по его ключу:
hash = {"1":{"id":1,"name":"John"},"2":{"id":2,"name":"Foo"},"3":{"id":3,"name":"Bar"}}
hash[1]
# Object { id=1, name="John"}