STI 和 RSpec 问题

发布于 2024-11-26 11:37:34 字数 839 浏览 3 评论 0原文

假设我有这些模型:

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”仅应用于开发数据库”)

Assume that I have these models:

class Person < ActiveRecord::Base
end

class Bob < Person
  def name
    'Bob'
  end
end

class John < Person
  def name
    'John'
  end
end

This code works well:

# in controller:
@persons = Person.all

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

But in my spec file I get error when I write something like this:

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

But this code works fine:

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

What do I do wrong?

P.S. The problem is only in RSpec files. The same code in controllers works well.

UPDATE: the solution is found! I should run "rake db:migrate RAILS_ENV=test" (last migration "add_type_to_person" was applied only to development database")

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紙鸢 2024-12-03 11:37:34

在运行测试之前,您可以使用此命令确保测试数据库的架构与开发数​​据库中的架构相匹配:

rake db:test:prepare

如果您使用 rake spec 调用 rspec,则准备工作将会为您进行。

You can make sure the schema of your test database matches the schema in your development database using this before running your tests:

rake db:test:prepare

If you invoke rspec using rake spec, the prepare will happen for you.

任性一次 2024-12-03 11:37:34

我们不知道您的架构或数据是什么样的。 (John 和 Bob 是表?)

不过,我不得不猜测 Person 没有 name 属性,这就是第一个测试失败的原因。

因为我不知道你想在这里做什么,所以我无法提供任何进一步的建议 - 但最简单的解决方案是将 name 方法放在 Person 对象上。 (假设它是某种虚拟列,也许您可​​以从数据中将其抽象出来,这样您就不必在子类中定义它。)

What we don't know is what your schema or data look like. (John and Bob are tables?)

I would have to guess, though, that Person does not have a name attribute, and that is why the first test fails.

Since I don't know what you are trying to do here, I can't advise any further -- but the simplest solution is to put the name method on the Person object. (Assuming that it's a virtual column of some sort, maybe you could abstract it out from the data so that you don't have to define it in the subclasses.)

野稚 2024-12-03 11:37:34

我猜问题出在你的装置上。我猜你的一个装置在 type 列中没有正确的值,并且偶然,这条记录恰好由 Person.all.first

Bob 返回.allPerson.all 不同 - 第一个将仅返回 type = "Bob" 的记录,第二个将返回所有记录记录。

通常在测试中使用 .first 不是一个好主意。通常您不知道(不指定)排序顺序,因此返回的记录是随机的。

在这种情况下,请检查失败测试返回的记录的 type 字段的值。我想会有一些线索。

I guess the problem is in your fixtures. I guess one of your fixtures does not have proper value in type column, and by accident, this one record happens to be returned by Person.all.first

Bob.all is not the same as Person.all - the first will return you only the records for which type = "Bob", the second will return all records.

Usually using .first in tests is not a good idea. Usually you do not know (do not specify) the sorting order, so the returned record is random.

In this case, check the value of the type field of the record returned by the failing test. I guess there will be some clue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文