【问题标题】:Model scopes are breaking rake db:migrate - rails 3.2.3 postgres 9.1.3模型范围正在破坏 rake db:migrate - rails 3.2.3 postgres 9.1.3
【发布时间】:2012-05-23 23:31:50
【问题描述】:

我在新的 Rails 应用程序 (3.2.3) 中运行迁移时遇到了问题。我们正在使用 postrgres 9.1.3 和 - pg (0.13.2) -

当我运行 rake db:create,然后 rake db:migrate,我得到 ->

1.9.3-p194 (master) rake db:migrate --trace
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
PG::Error: ERROR:  relation "roles" does not exist
LINE 4:              WHERE a.attrelid = '"roles"'::regclass
                                    ^
:             SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
          FROM pg_attribute a LEFT JOIN pg_attrdef d
            ON a.attrelid = d.adrelid AND a.attnum = d.adnum
         WHERE a.attrelid = '"roles"'::regclass
           AND a.attnum > 0 AND NOT a.attisdropped
         ORDER BY a.attnum

即使没有定义任何迁移,我也会得到这个,所以我不认为这是迁移本身的问题。当我查看堆栈跟踪时,我看到在我的用户模型中定义的范围正在运行 - 当我将它们注释掉时,迁移运行没有问题。

scope :team_leaders, where(role_id: Role.where(name: 'Team Leader').first.try(:id))
scope :area_leaders, where(role_id: Role.where(name: 'Area Leader').first.try(:id))
scope :nation_leaders, where(role_id: Role.where(name: 'Nation Leader').first.try(:id))
scope :employees, where(role_id: Role.where(name: 'Employee').first.try(:id))

这是 Rails 中的错误,还是我做错了什么?非常感谢一些帮助 - 我们可以在整个应用程序中删除这些范围的使用,但这是我们想要避免的。

我是否应该将这些范围放在某种条件中,当 Rails 加载到控制台或作为服务器时调用,而不是在迁移期间调用?

非常感谢,

丹·索特

【问题讨论】:

  • 看起来角色表不是在 db:create 中创建的。角色有迁移吗?您使用的是 acl9 或 role_requirement 之类的角色插件吗?如果是这样,请确保您没有遗漏需要运行的生成器。
  • 您可能还想尝试将导致您出现问题的范围包装在 lamda 中,以便在实际使用它们之前不会对其进行评估。

标签: ruby-on-rails ruby postgresql ruby-on-rails-3.2


【解决方案1】:

我遇到了完全相同的问题。经过 2 个小时的调试并拔掉我的头发后,这个名为 Carl Zulauf 的有福的人在 cmets 中发布了答案。

问题是我们在运行迁移时正在评估范围,因此与尚未迁移的另一个表的任何依赖关系都会导致该错误。

只需使用 lambda 包装所有作用域。例如:

scope :team_leaders, lambda { where(role_id: Role.where(name: 'Team Leader').first.try(:id)) }

对所有范围都这样做。

这应该可以解决问题。他们需要惰性评估(仅在被调用时),并且没有lambda,他们会立即被评估。

【讨论】:

  • 非常感谢尼古拉斯。抱歉,我没有早点回复 - lambda 解决方案正是我所做的,并且它有效。我尝试将范围包装在某种除非 Rails.env == 'migration' 概念中,但 lambda 是赢家。
  • 你应该在迁移中使用作用域吗?我认为这是不好的做法,因为如果您突然想对该范围添加更改,那么如果您回滚,那可能不一定与您之前的迁移保持一致。(仅供参考,如果有关于如何进行的解释,我仍然是 Rails 新手处理这个)
【解决方案2】:

如果您的作用域以find_ 开头,例如find_by_foo,那么它们将中断rake db:migrate。 这就是我的问题。

【讨论】:

  • 我遇到了同样的问题,我将范围名称从 find_by_foo 更改为 search_by_foo
【解决方案3】:

我实际上对默认范围引起的迁移有同样的问题,如下所示:

default_scope where(deleted: false)

错误是由这样的代码块引起的:

ModelName.all.each_with_index do |m, i|
...
end

这个问题通过取消作用域解决了:

ModelName.unscoped.each_with_index do |m, i|
...
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-09
    • 2011-11-19
    相关资源
    最近更新 更多