web-dev-qa-db-fra.com

Erreur d'argument: le corps de la portée doit être appelable

Je suis en train de suivre la «formation essentielle à Ruby on Rails 3» et un problème est survenu lors de l'utilisation de domaines de noms. Lors de la recherche d'enregistrements et de l'utilisation de requêtes avec la console Rails, tout s'est bien passé jusqu'à ce que j'essaie d'utiliser une étendue de nom dans mon fichier subject.rb. Ceci est mon code dans le fichier subject.rb. 

Class Subject < ActiveRecord::Base

  scope :visible, where(:visible => true)

end   

J'ai enregistré le fichier .rb et redémarré la console Rails, mais lorsque je l'exécute à partir de la console Rails:

subjects = Subject.visible

Je reçois: ArgumentError: The scope body needs to be callable.

Est-ce que quelqu'un sait pourquoi je reçois cette erreur?.

39
Sam Gruse

Le corps de la portée doit être enveloppé dans quelque chose appelable comme un Proc ou un Lambda:

scope :visible, -> {
  where(:visible => true)
}

La raison en est qu’elle garantit que le contenu du bloc est évalué chaque fois que l’étendue est utilisée.

73
infused

Oui, c’est la façon dont Rails 4 appelle les scopes. Vous devrez le changer si vous effectuez une mise à niveau vers Rails 4 à partir de Rails 3.

3
Pradeep S

J'ai eu la même erreur, alors qu'avant ma solution j'avais un espace entre where et ( comme ci-dessous

scope :registered , -> { where ( place_id:  :place_id , is_registered: :true ) }

après avoir supprimé l’espace entre where et ( comme ci-dessous j’ai fait fonctionner ma page 

scope :registered , -> { where( place_id:  :place_id , is_registered: :true ) }
3
ImranNaqvi

Ce que vous utilisez: scope :visible, where(:visible => true) permet un chargement rapide et est déconseillé dans Rails 4.

scope :visible, where(:visible => true)

Cette ligne de code est évaluée lorsque la classe particulière est chargée et pas à ce moment-là, cette très scope est appelée .

Il y a quelques cas où cette chose est importante, comme:

scope :future, where('published_at > ?', Time.now)
scope :future, -> { where('published_at > ?', Time.now) }

Dans le premier cas, ? sera remplacé par l'heure à laquelle la classe aurait été chargée, mais dans le second et le cas correct, cette heure sera utilisée à laquelle l'étendue aurait été appelée dans la classe.

0
Arslan Ali