3

我有一个类层次结构如下所示:

class Post < ActiveRecord::Base; end
class Project < Post; end
class ProjectDesignWall < Project; end

有一个控制器可以像这样获取数据:

@projects = Project.find(:all, :include => [:project_image_photos,:user])

development中,这会直接从日志中运行以下查询:

SELECT * FROM `posts` WHERE ( (`posts`.`type` = 'Project' ) ) ORDER BY originally_created_at DESC

但是,一旦它在production模式下运行,即使使用相同的数据库和数据,它也会导致以下查询:

SELECT * FROM `posts` WHERE ( (`posts`.`type` = 'Project' OR `posts`.`type` = 'ProjectDesignWall' ) ) ORDER BY originally_created_at DESC

有谁知道为什么会这样,如果不能彻底解决问题,有没有办法让它至少表现一致?

4

2 回答 2

5

因为在生产环境中,你所有的类都是一次性加载的。当所有类都加载时,它会意识到 ProjectDesignWall 是 Project 的子类,因此会收集所有类。

于 2009-04-01T06:35:50.473 回答
2

此处有此错误的公开票: https ://rails.lighthouseapp.com/projects/8994/tickets/188-single-table-inheritance-bug-only-in-production-environment

解决方案列在这张票的底部:https ://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2389-sti-changes-behavior-depending-on-environment

去引用:

您必须在父类中显式命名子类

类 ProjectFeedEvent < FeedEvent

def self.subclasses
  [ProjectAddedEvent]
end  

结尾

这个问题已经存在了一段时间并且没有受到太多关注的部分原因是 STI 在 Rails 中通常不是必需的。大多数 Rails 贡献者决定不在他们自己的项目中使用它,因此没有花时间确保它得到很好的支持。这里有一个简介,简要解释了为什么你不应该使用它并提出一个替代方案:http: //www.matthewpaulmoore.com/ruby-on-rails-code-quality-checklist#sti

我自己在公司使用 STI 的个人经验是,起初这似乎非常有用,但随着时间的推移,我们确定我们根本不需要它来保证复杂性。从那时起,我们的项目急剧增长,我们根本没有错过它。

于 2009-04-02T07:16:50.010 回答