As views de array desta aplicação tomam o caminho simples
O curso de nível Júnior "Desenvolvimento de API: Jbuilder" leu as views .json.jbuilder desta aplicação. Várias montam arrays: a busca do catálogo por trás da paleta de comandos, e as listas de alunos, certificados e atividade da API de parceiros. A view da busca é a mais simples:
json.array! @result.courses + @result.lessons do |item|
if item.is_a?(::Catalog::Course)
json.title item.title
json.url catalog_course_path(item.slug)
json.type "course"
json.level item.level
else
json.title "#{item.course.title}: #{item.title}"
json.url catalog_lesson_path(course_slug: item.course.slug, slug: item.slug)
json.type "lesson"
json.level item.course.level
end
end
É um bloco, chamado uma vez por item. É a forma mais simples do array!, e todo array nas views JSON da aplicação é montado assim ou com um map simples. Esta aula trata do que essa forma faz, e do que ela não consegue fazer.
O array!, na gem instalada
# jbuilder-2.15.1/lib/jbuilder/jbuilder_template.rb
def array!(collection = EMPTY_ARRAY, *args, &block)
options = args.first
if _partial_options?(options)
options = options.dup
options[:collection] = collection
_render_partial_with_options options
else
_array collection, args, &block
end
end
def _partial_options?(options)
::Hash === options && options.key?(:as) && options.key?(:partial)
end
Há um if. A chamada da view de busca, json.array! collection do |item| ... end, não tem segundo argumento, então o options é nil e o _partial_options? devolve falso na hora. O array! vai para o _array, que, com um bloco, percorre a coleção. Ele entrega cada item ao bloco, captura os atributos que o bloco define e os acrescenta a um Array simples. Não há template, partial nem cache.
Os resultados de busca da aplicação, por esse caminho
Em desenvolvimento:
result = Catalog::SearchQuery.call(query: "ruby", locale: :en)
renderer = ApplicationController.renderer
renderer.render(inline: 'json.array! @items do |c| json.title c.title end', type: :jbuilder, assigns: { items: result.courses })
resultado da busca: 8 cursos, 8 aulas
saída da forma com bloco: [{"title":"Ruby: programmer happiness"},{"title":"Ruby variables & assignment"},
{"title":"Ruby symbols vs strings"},{"title":"Ruby data: numbers & booleans"}, ...
São os títulos de curso da própria aplicação, serializados pelo mesmo caminho da forma com bloco que a view de busca roda a cada requisição. O SearchQuery::LIMIT = 8 é o motivo de a saída parar em 8 cursos e 8 aulas, e esse número volta a importar na aula 6.
O que a forma com bloco não consegue fazer
O _partial_options? só devolve verdadeiro quando o segundo argumento é um Hash com :as e :partial. Uma chamada só com bloco não tem hash de opções em que o cached: possa ser uma chave. O cache não está desligado em algum lugar. O caminho com bloco nunca procura uma opção cached:, porque o ramo que a lê é o outro, o ramo que o _partial_options? protege. A aula 2 segue esse ramo, que nenhuma view JSON da aplicação usa.
Pontos-chave
- A view de busca,
catalog/search/index.json.jbuilder, chama oarray!só com um bloco, e as views da API de parceiros montam os arrays do mesmo jeito ou commap. - O
array!se divide pelo_partial_options?, que exige umHashcom:ase:partial. Um bloco sozinho nunca atende a isso, então a chamada vai para o_arraye um bloco simples por item. - Rodado sobre os resultados do
SearchQueryda aplicação, esse caminho produziu os títulos de curso da aplicação, o mesmo mecanismo que o endpoint de busca usa. - A forma com bloco não tem opção
cached:a passar: não é uma configuração esquecida, e sim um ramo doarray!que a chamada com bloco nunca alcança.
Continue com a aula 2
O caminho de partial-e-cache que esta aplicação nunca usou
Roda o array! com partial:, as: e cached: nos dados de busca, com uma leitura e uma gravação em lote.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.