Pluck é um ActiveRecord
método de cálculo introduzido em novembro de 2011 e é projetado para retornar uma coleção de valores executando uma única SELECT
consulta 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 all
registros do User
ActiveRecord
objeto 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..select
User
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 pluck
mé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 User
registros AR completos e, em seguida, executou o map
, este exemplo foi diretamente para o banco de dados com uma SQL
chamada 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'