portées avec lambda et arguments dans le style Rails 4?


144

Je me demande comment ce qui suit est fait dans Rails 4 ou si j'utilise simplement l'approche Rails 3 pour utiliser un lambda qui peut passer un argument de la même manière avec 4 que je le fais avec 3.

Je suis assez nouveau dans Rails 3 et j'essaie de travailler sur quelques exemples exécutant Rails 4.

Voici mon code Rails 3:

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

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

Donc, si c'est la façon dont Rails 4 utilise le -> {}, c'est un lambda, non? scope :all_lazy, -> { select("*") }Et si j'avais besoin d'un argument. J'ai essayé quelques idées différentes et j'obtiens des erreurs d'argument dans la console lors de l'utilisation de -> {}.

Réponses:


305

Je pense que ça devrait être:

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

2
Documentation à l'appui , section 14.1 spécifiquement.
Dennis

3
Ouais, m'a aidé à écrirescope :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
Notez que si vous utilisez Ruby 1.9, la syntaxe lambda courte ne permet pas d'espace entre la flèche et un paramètre ( scope :find_lazy, ->(param)). Dans Ruby 2+, l'espace est autorisé. Plus d'infos ici ...
furman87

Syntex "moderne" en rubisscope :find_lazy, -> id { where id: id }
swordray

11

Ruby n'a pas non plus désapprouvé l'ancien style de lambda, donc si vous vous sentez plus à l'aise avec cela, allez-y.

Personnellement, je n'aime pas moi-même la syntaxe du lambda stabby, mais elle deviendra probablement la norme, donc ça ne fait pas de mal de s'y habituer.


6
J'aime la syntaxe, mais il semble tout à fait faux de placer les arguments entre la flèche et le corps de la fonction, alors que cela aurait dû être "(id) -> {where ...}", ce qui serait beaucoup plus attrayant (et ne le serait pas non plus rompre avec mes connaissances en mathématiques ni avec la syntaxe coffeescript). À la fin, "->" dit quelque chose comme le mappage de valeurs à un résultat.
hurikhan77

Je suis tombé sur une situation où l'utilisation de l'ancien style dans Rails 4.2 renvoyait des valeurs booléennes incorrectes de la base de données. Il n'est peut-être pas officiellement obsolète, mais l'utilisation de la syntaxe mise à jour a résolu le problème.
stevenspiel

1
@ hurikhan77 Oui, il est déconcertant que la syntaxe entre en conflit avec CoffeeScript coffeescript.org/#functions
Chloé

8

Rails 4, vous pouvez faire:

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

C'était dans le vieux rubis:

:id => id

Meilleur hachage:

id: id

5

mec j'utilisais habituellement la syntaxe de programmation ci-dessous

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

Mais lorsque j'ai examiné mon code à l'aide de Codacy, je l'ai trouvé m'alerter sur cette syntaxe

Use the `lambda` method for multiline lambdas.

Je l'ai changé pour être et ça marche bien

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

2

Pour soutenir les associations:

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

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

est équivalent à

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

Basé sur le guide rubis sur rails :Using a class method is the preferred way to accept arguments for scopes.

Il n'y a aucune raison d'utiliser des étendues avec des lambdas de préférence aux méthodes de classe. C'est une question de préférence personnelle. Mais, si vous souhaitez suivre les instructions, vous devez utiliser la méthode de classe lorsque des arguments sont impliqués.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.