escopos com lambda e argumentos no estilo Rails 4?

144

Gostaria de saber como é feito o seguinte no Rails 4 ou se apenas uso a abordagem do Rails 3 para usar um lambda que pode passar um argumento da mesma maneira com 4 do que com o 3.

Eu sou muito novo no Rails 3 e estou tentando trabalhar com algumas amostras executando o Rails 4.

Aqui está o meu código do Rails 3:

class Person < ActiveRecord::Base
  scope :find_lazy, lambda {|id| where(:id => id)}
end

# In console I can call
Person.find_lazy(1)

Portanto, se essa é a maneira do Rails 4, é usar o -> {}, isso é um lambda, certo? scope :all_lazy, -> { select("*") }E se eu precisasse de uma discussão. Tentei algumas idéias diferentes e obtive erros de argumento no console ao usar o -> {}.

Kaplan
fonte

Respostas:

305

Eu acho que deveria ser:

scope :find_lazy, -> (id) { where(id: id) }
lis2
fonte
2
Documentação de suporte , seção 14.1 especificamente.
Dennis
3
Yay, me ajudou a escreverscope :in_daterange, ->(start_date, end_date) { where(created_at: start_date.to_date.beginning_of_day..end_date.to_date.end_of_day) }
Epigene
4
Observe que se você estiver usando Ruby 1.9, a sintaxe lambda curta não permitirá um espaço entre a seta e um parâmetro ( scope :find_lazy, ->(param)). No Ruby 2+, o espaço é permitido. Mais informações aqui ...
furman87
Syntex "Modern" em Rubyscope :find_lazy, -> id { where id: id }
swordray
11

O Ruby também não obsoleta o estilo antigo do lambda; portanto, se você se sentir mais confortável usando isso, faça o mesmo.

Pessoalmente, eu não gosto da sintaxe do stabby lambda, mas, eventualmente, elas provavelmente se tornarão a norma, portanto não faz mal se acostumar com elas.

Branden Silva
fonte
6
Eu gosto da sintaxe, mas parece errado colocar os argumentos entre a seta e o corpo da função, enquanto deveria ter sido "(id) -> {where ...}" que seria muito mais atraente (e não seria romper com meus conhecimentos de matemática nem com sintaxe de café). No final, "->" diz algo como mapear valores para um resultado.
Hurikhan77
Eu me deparei com uma situação em que o uso do estilo antigo no Rails 4.2 estava retornando valores booleanos incorretos do banco de dados. Pode não ser oficialmente descontinuado, mas o uso da sintaxe atualizada corrigiu o problema.
Stevenspiel
1
@ hurikhan77 Sim é desconcertante que os conflitos de sintaxe com Coffeescript coffeescript.org/#functions
Chloe
8

Rails 4, você pode fazer:

scope :find_lazy, -> (id) { where(id: id) }

Isso estava no velho rubi:

:id => id

Melhor hash:

id: id
sesperanto
fonte
5

cara, eu usava normalmente a sintaxe de programação abaixo

scope :find_lazy, -> (id) { where(id: id) }

Mas quando eu estava revisando meu código usando o Codacy, achei que estava me alertando sobre essa sintaxe

Use the `lambda` method for multiline lambdas.

Eu mudei para ser e está funcionando bem

  scope :find_lazy, lambda {|id|
    where(id: id)
  }
Astm
fonte
2

Para apoiar associações:

scope :find_lazy, -> (object) { where(object_id: object.id) }
tokhi
fonte
1
scope :find_lazy, -> (id) { where(id: id) }

é equivalente a

self.find_lazy(id)
  where(id: id)
end

Baseado no guia Ruby on Rails :Using a class method is the preferred way to accept arguments for scopes.

Não há razão para usar escopos juntamente com lambdas, de preferência aos métodos de classe. É uma questão de preferência pessoal. Mas, se você quiser seguir as diretrizes, use o método de classe quando houver argumentos envolvidos.

mmsilviu
fonte