Проблема с STI и RSpec - PullRequest
0 голосов
/ 27 июля 2011

Предположим, что у меня есть следующие модели:

class Person < ActiveRecord::Base
end

class Bob < Person
  def name
    'Bob'
  end
end

class John < Person
  def name
    'John'
  end
end

Этот код хорошо работает:

# in controller:
@persons = Person.all

# in view:
- @persons.each do |person|
  %p= person.name

Но в моем файле спецификации я получаю сообщение об ошибке, когда пишу что-то вроде этого:*

it "display person names" do
  Bob.create!
  @person = Person.all.first
  print @person.name # Error: undefined method 'name' for #<Person:0x...>
end

Но этот код работает нормально:

it "display person names" do
  Bob.create!
  @person = Bob.all.first
  print @person.name
end

Что я делаю не так?

PS Проблема только в файлах RSpec.Тот же код в контроллерах работает хорошо.

ОБНОВЛЕНИЕ: решение найдено!Я должен запустить "rake db: migrate RAILS_ENV = test" (последняя миграция "add_type_to_person" была применена только к базе данных разработки ")

Ответы [ 3 ]

0 голосов
/ 27 июля 2011

Полагаю, проблема в ваших приспособлениях. Я полагаю, что одно из ваших приборов не имеет правильного значения в столбце type, и случайно эта запись возвращается Person.all.first

Bob.all - это не то же самое, что Person.all - первый вернет вам только те записи, для которых type = "Bob", второй вернет все записи.

Обычно использование .first в тестах не очень хорошая идея. Обычно вы не знаете (не указываете) порядок сортировки, поэтому возвращаемая запись является случайной.

В этом случае проверьте значение поля type записи, возвращенной при неудачном тесте. Я думаю, что будет какая-то подсказка.

0 голосов
/ 27 июля 2011

Вы можете убедиться, что схема вашей тестовой базы данных совпадает со схемой в вашей базе данных разработки, перед запуском ваших тестов:

rake db:test:prepare

Если вы вызываете rspec с помощью rake spec, подготовка произойдет длявы.

0 голосов
/ 27 июля 2011

Чего мы не знаем, так это как выглядит ваша схема или данные. (Джон и Боб - столы?)

Я должен был бы предположить, однако, что Person не имеет атрибута name, и именно поэтому первый тест не пройден.

Поскольку я не знаю, что вы пытаетесь сделать здесь, я не могу давать дальнейших советов, но самое простое решение - поместить метод name в объект Person. (Предполагая, что это какой-то виртуальный столбец, возможно, вы могли бы абстрагировать его от данных, чтобы вам не приходилось определять его в подклассах.)

...