Nested JSONs com Ruby on Rails.

Não sei se o título do Post foi o mais correto, mas ao meu ver foi o mais próximo do propósito que quero passar.

Seja pelo crescimento de frameworks Javascript para consumi-las ou a necessidade de interfaces mobile, o importante é que a demanda por APIs aumenta a cada dia no mercado de desenvolvimento.

Recentemente em meus estudos me deparei com uma necessidade comum, mas que nunca havia pensado nisso como um retorno a uma requisição JSON, como renderizar dados de um Model associado ao meu Model principal?

Compliquei? Vou utilizar meu exemplo real. Construí uma API que mantém clubes de futebol e alguns jogadores ligados a cada clube, ou seja:

club.rb

has_many :players

player.rb

belongs_to :club

Sabendo disso, sempre que um cliente realizar uma requisição ao método show de um determinado clube, além dos dados do clube é necessário retornar também os jogadores associados ao clube, exemplo:

Ao acessar minha aplicação em http://localhost:3000/clubs/1, essa seria a resposta esperada.

{ 
id: 1,
name: “Chelsea F.C.”,
country: “England”,
players: [
{name: “John Terry”, birthday: "1980-11-07", club_id: 1},
{name: “Frank Lampard”, birthday: "1978-06-20", club_id: 1}
]
}

O JSON retornado trouxe as informações do clube (não incluí timestamps) e os dados de cada jogador ligado ao clube.

Utilizando a gem rails-api que agora é nativa do Rails, na action show do clubs_controller.rb ficaria assim:

def show 
render json: @club.to_json(include: [:players])
end

Já resolveria meu problema, mas se eu quisesse exibir apenas algumas informações do jogador? Como no exemplo eu não estou exibindo timestamps, a exibição do JSON ficaria um pouco mais poluída do que está. Vamos dizer que preciso apenas do nome dos jogadores ligados ao clube:

def show 
render json: @club.to_json(include: {:players =>
{ :only => :name }
})
end

Assim a resposta da requisição será esta, sabendo que :name é um atributo do Model Player:

{ 
id: 1,
name: “Chelsea F.C.”,
country: “England”,
players: [
{name: “John Terry”},
{name: “Frank Lampard”}
]
}

É isso ai, espero que o exemplo ajude e para mais informações ou outros exemplos, só dar uma olhada aqui. Valeu !