As views de array desta aplicação tomam o caminho simples

Prévia grátis 3 min de leitura

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 o array! só com um bloco, e as views da API de parceiros montam os arrays do mesmo jeito ou com map.
  • O array! se divide pelo _partial_options?, que exige um Hash com :as e :partial. Um bloco sozinho nunca atende a isso, então a chamada vai para o _array e um bloco simples por item.
  • Rodado sobre os resultados do SearchQuery da 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 do array! que a chamada com bloco nunca alcança.
Aula 1 de 7 · grátis

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.

Digite para buscar...