Вас бентежить "response_to" проти "response_to?"


79

Я вивчаю Rails з railstutorial.org, і мене щось бентежить: у цьому розділі автор пропонує нам провести тестування в консолі з respond_to?методом на об'єкті User, і це працює нормально. Але пізніше, коли ми пишемо тест на :encrypted_passwordатрибут, він використовує respond_to.

З цікавості я спробував respond_toу консолі об’єкт User, і з’являється повідомлення про помилку, що метод не існує. На жаль, якщо я спробую написати тест, використовуючи respond_to?замість respond_to, тест не запускається.

Хтось може пояснити мені різницю, і чому тест працює тільки з respond_to?

Відповіді:


171

Рубі розглядає ?і !як фактичні символи в назві методу. 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 ви бачите метод RSpec, який shouldвзаємодіє з respond_toметодом RSpec . Це не буде доступно у вашій консолі, якщо ви не запустите rails console test.


Але якщо ви читаєте приклад у книзі, response_to використовується не з типом запиту, а з атрибутом. Може Rails перевизначає метод Ruby, тому він також приймає атрибути?
agente_secreto

1
Це метод RSpec для тестування: rspec.info/documentation ... він не буде доступний у консолі, якщо ви не встановите для ENV тестування.
Тім Салліван

3
Я вважаю, що це дуже дивно, що творці Ruby вирішили використовувати одне і те ж ім'я виразу "response_to" для двох різних речей: виявити, чи має об'єкт метод АБО відповісти на тип запиту. О так, є? що робить їх різними. Ого. \ o /
Junior Mayhé

4
Це зовсім не творці Ruby. Перший - це метод Рубі. Другий - це метод Rails на ActionController. Третій - це метод бібліотеки RSpec. ? і! в Ruby мають значення, тож різниця між response_to та response_to? дорівнюють різниці між обробкою та обробкою.
Тім Салліван,

2
Щоб майбутні користувачі не заплуталися, ?кінець імені методу в ruby не гарантує повернення методом логічного значення. Це ?лише частина назви методу, як і будь-який інший символ. Те, що методи знаків запитання повинні повертати логічну форму, є усталеною умовою, але вона не є загальнодоступною. (Дивись, наприклад , github.com/rails/rails/pull/5329 і метушня виникає , коли метод знак питання не повертають логічне значення)
Andrew

4

respond_to?є булевою оцінкою. respond_toВикористовується (зазвичай) для визначення інформації на дисплеї. Більше інформації тут . У respond_to?перевіряє, якщо метод існує і повертає істину , якщо вона робить , і помилково , якщо воно не робить.


3

Тест використовує зручні помічники, щоб бути зручнішими для користувачів.

Ruby - це Ruby, тому використання старого доброго respond_to?буде працювати, якщо ви називаєте це так:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.