Dicas rápidas do Rails – ActiveRecord :: Calculations.pluck

Flor sendo arrancada

Pluck é um ActiveRecordmétodo de cálculo introduzido em novembro de 2011 e é projetado para retornar uma coleção de valores executando uma única SELECTconsulta de coluna como direta SQL.

Agora, que problema isso poderia ajudar a resolver e como isso nos afeta?

Com que frequência você encontrou algum código semelhante a este?

users = User.all
=> [#<User id: 1, email: 'dude@example.com', active: true>, #<User id: 2, email: 'sweet@example.com', active: false>]

users
.map(&:email)
=> ['dude@example.com', 'sweet@example.com']

# I've separated the AR result from the ruby #map for clarity
# this would normally be called as User.all.map(&:email)

O que esta acontecendo aqui?

Estamos retornando allregistros do User ActiveRecordobjeto e solicitando uma nova coleção contendo cada um email. Ele definitivamente dá conta do recado … precisamos mesmo consertar isso? Possivelmente. Essa decisão definitivamente caberá à pessoa implementada, mas vamos explorar uma maneira diferente de obter o mesmo resultado de uma forma mais eficiente e com melhor desempenho.

ActiveRecord retornará registros AR como resultado, mas somente retornará com os atributos explicitamente solicitados. A classe ainda está sendo instanciada para cada resultado. Dependendo das restrições de memória, isso pode não ser um problema, mas, no entanto, está usando memória que simplesmente não precisava ser usada..selectUser

emails = User.select(:email)
=> [#<User email: 'dude@example.com'>, #<User email: 'sweet@example.com'>]

emails
.map(&:email)
=> ['dude@example.com', 'sweet@example.com']

Estamos chegando mais perto. Pelo menos agora estamos apenas retirando os dados que nos interessam. Isso é apenas ligeiramente melhor do que nossa primeira tentativa e parece estranho. Pedimos para selecionar apenas um atributo específico e, em seguida, temos que pedir que seja a única coisa em uma coleção.

Vamos tentar mais uma vez usando o pluckmétodo.

User.pluck(:email)
=> ['dude@example.com', 'sweet@example.com']

Uau! Bem, isso é um pouco diferente. Definitivamente menos código, mas o que está fazendo? .plucké um método de cálculo (mal colocado?) que, como descrito acima, está retornando uma matriz de resultados com base na coluna do banco de dados que foi solicitada. Onde o exemplo anterior retornou Userregistros AR completos e, em seguida, executou o map, este exemplo foi diretamente para o banco de dados com uma SQLchamada e retornou apenas o resultado necessário. Em muitos casos, isso é muito mais limpo e definitivamente mais eficiente.

Além disso, outros métodos de relação podem ser encadeados e afetam a consulta de resultado final que é gerada.

User.where(active:true).pluck(:email)
SELECT email FROM 'users' WHERE 'users'.'active' = 't'

Artigo original