Ошибка аргумента: тело области должно быть вызываемым

Я работаю над "Ruby On Rails 3 Essential Training" и столкнулся с проблемой при использовании областей имен. При поиске записей и использовании запросов в консоли Rails все шло гладко, пока я не попытался использовать область имен в моем файле subject.rb. Это мой код в файле subject.rb.

Class Subject < ActiveRecord::Base

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

end   

Я сохранил файл .rb и перезапустил консоль Rails, но когда я запускаю ее из консоли rails:

subjects = Subject.visible

Я получаю: ArgumentError: The scope body needs to be callable.

Кто-нибудь знает, почему я получаю эту ошибку.


person Sam Gruse    schedule 09.03.2015    source источник


Ответы (4)


Тело области должно быть обернуто чем-то вызываемым, например Proc или Lambda:

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

Причина этого в том, что это гарантирует, что содержимое блока оценивается каждый раз, когда используется область.

person infused    schedule 09.03.2015
comment
Хорошо, это имеет смысл, и я не могу дождаться, чтобы попробовать это завтра утром, чтобы я мог продолжить обучение. Спасибо за быстрый ответ. Любые догадки, почему инструктор не использовал обертку в своем примере. Кажется, с ним это сработало. Я также заметил, что новейшая версия ruby ​​не использует маркировку: self.up self.down. Инструктор сказал, что Ruby не нуждается в этом в более новых версиях, но мне пришлось включить его, чтобы миграция работала. Это сбивает с толку, когда есть разные версии рельсов, так как были сделаны обучающие видео. Спасибо еще раз. - person Sam Gruse; 10.03.2015
comment
@SamGruse это способ сделать это в Rails 4, курс, кажется, использует Rails 3 - person reillyse; 10.04.2015

Я получил ту же ошибку, хотя до моего решения у меня был пробел между where и (, как показано ниже.

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

после того, как я удалил пробел между where и (, как показано ниже, моя страница заработала

scope :registered , -> { where( place_id:  :place_id , is_registered: :true ) }
person ImranNaqvi    schedule 15.10.2015

Да, действительно, это рельсы 4, способ вызова областей. Вам нужно будет изменить его, если вы переходите на Rails 4 с Rails 3.

person Pradeep S    schedule 15.09.2015

Что вы используете: scope :visible, where(:visible => true) используется для быстрой загрузки и устарело в Rails 4.

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

Эта строка кода оценивается, когда загружается конкретный класс, а не во время вызова этого самого scope.

Есть несколько случаев, когда это имеет значение, например:

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

В первом случае ? будет заменено на то самое время, когда класс был бы загружен, но во втором и правильном случае будет использоваться то время, в которое область видимости была бы вызвана для класса.

person Arslan Ali    schedule 26.08.2016