Не знаете, что такое "response_to" или "reply_to"?

79

Я изучаю Rails с помощью railstutorial.org, и меня кое-что смущает: в этой главе автор говорит нам провести некоторое тестирование в консоли с помощью respond_to?метода объекта User, и он работает нормально. Но позже, когда мы напишем тест для :encrypted_passwordатрибута, он использует respond_to.

Из любопытства я попытался respond_toнайти в консоли объект User и получил сообщение об ошибке, в котором говорится, что метода не существует. Увы, если я попытаюсь написать тест с использованием respond_to?вместо respond_to, тест не запустится.

Может ли кто-нибудь объяснить мне разницу, и почему тест запускается только с respond_to?

Agentte_secreto
источник

Ответы:

171

Ruby рассматривает ?и !как фактические символы в имени метода. respond_toи respond_to?разные. ?указывает, что это должно отвечать истиной или ложью (по соглашению; это не требование). В частности:

respond_to?- это метод Ruby для определения того, есть ли в классе конкретный метод. Например,

@user.respond_to?('eat_food')

вернет true, если у Userкласса есть eat_foodметод.

respond_toэто метод Rails для ответа на определенные типы запросов. Например:

def index
  @people = Person.find(:all)

  respond_to do |format|
    format.html
    format.xml { render :xml => @people.to_xml }
  end
end

Однако в предоставленной вами ссылке RailsTutorial вы видите, что метод RSpecshould взаимодействует с respond_toметодом RSpec . Это не будет доступно в вашей консоли, если вы не запустите rails console test.

Тим Салливан
источник
Но если вы читали пример в книге, response_to используется не с типом запроса, а с атрибутом. Может быть, Rails переопределяет метод Ruby, поэтому он также принимает атрибуты?
Agentte_secreto
1
Это метод RSpec для тестирования: rspec.info/documentation ... он не будет доступен в консоли, если вы не установите ENV на тестирование.
Тим Салливан
3
Мне очень странно, что создатели Ruby решили использовать одно и то же имя оператора «response_to» для двух разных целей: определить, есть ли у объекта метод, ИЛИ ответить на тип запроса. Ах да, есть? это их отличает. Вау. \ o /
Junior Mayhé
4
Это были вовсе не создатели Ruby. Первый - это метод Ruby. Второй - это метод Rails для ActionController. Третий - это метод библиотеки RSpec. ? и ! в Ruby имеют значение, поэтому разница между response_to и response_to? равны разнице между триммером и триммером.
Тим Салливан
2
Чтобы будущие пользователи не запутались, ?знак в конце имени метода в ruby не гарантирует, что метод вернет логическое значение. Это ?просто часть имени метода, как и любой другой символ. То, что методы вопросительного знака должны возвращать логическое значение, - это устоявшееся соглашение, но оно не соблюдается повсеместно. (см., например, github.com/rails/rails/pull/5329 и суматоху, вызванную, когда метод вопросительного знака не возвратил логическое значение)
Эндрю
4

respond_to?является логическим вычислением. respond_toИспользуется (обычно) для определения информации на дисплее. Больше информации здесь . В respond_to?проверяет, если метод существует и возвращает истину , если она делает , и ложно , если оно не делает.

Micharch54
источник
3

В тесте используются удобные помощники, чтобы сделать его более удобным.

Ruby - это Ruby, поэтому использование старого доброго respond_to?будет работать, если вы назовете его так:

 @user.respond_to?(:encrypted_password).should be_true

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

апноэ
источник