2

我们将 ActiveAdmin 和 CircleCI 与 Postgres 和 Rails 3 一起使用。它工作正常,但在添加新的 ActiveAdmin 模型后,我们在以下过程中得到了这个rake db:create db:schema:load

PG::UndefinedTable: ERROR:  relation "external_videos" does not exist
...
/home/ubuntu/Swearnet/app/models/external_video.rb:11:in `<class:ExternalVideo>'
/home/ubuntu/Swearnet/app/models/external_video.rb:1:in `<top (required)>'
...
/home/ubuntu/Swearnet/vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.14/lib/active_support/dependencies.rb:190:in `const_missing'
/home/ubuntu/Swearnet/app/admin/external_video.rb:1:in `<top (required)>'
...
/home/ubuntu/Swearnet/config/routes.rb:54:in `block in <top (required)>'

如果我们删除新文件(即使这个文件与我们的任何其他 ActiveAdmin 文件没有本质区别),错误就会消失。

这个错误似乎是路由导致 ActiveAdmin 加载,这导致 ExternalVideo 模型被自动加载,这导致它查找尚未创建的 external_videos 表。为什么我们的其他 ActiveAdmin 文件不会发生这种情况?以前有没有其他人遇到过这种问题?

我们的新文件app/admin/external_videos.rb看起来像:

ActiveAdmin.register ExternalVideo do
  menu :parent => "Shows"

  form do |f|
    f.inputs nil do
      f.input :title
      f.input :description
      f.input :published_at
      f.input :expires_at
    end
    f.actions
  end
end

编辑:我们发现了问题...... ExternalVideo 上有一个名为find_by_sxg_id. 当我们将该范围重命名为时,get_by_sxg_id一切正常。我不知所措......我知道这find_by通常是一个神奇的 ActiveRecord 前缀,但不确定在 rake 任务中创建表之前,仅仅是定义如何导致表被访问......

4

2 回答 2

4

为了任何寻求更多信息的人的利益,我希望这些信息有所帮助。在 activeadmin 的上下文中,我们在两个地方遇到了这个问题。

1. 在搜索过滤器上定义集合时未能声明 proc {}。

例如:

filter :association_id, as: :select, collection: Association.all, label: "Association"

应该

filter :association_id, as: :select, collection: proc { Association.all }, label: "Association"

将模型加载推迟到实际加载索引页面并允许 Circle CI 完成 db:schema:load (或执行 db:schema:load 的 rake 任务)

2. 注册资源会加载模型定义,因此,如果有任何方法定义需要模型实例化,Circle CI 会给您 Postgres 错误,您将一无所获。

这是一个比较棘手的发现,尽管事后看来它应该是显而易见的。因此,例如,如果您有一个状态为“initial、active、inactive”的“roll-your-own”状态机,并且您想定义一组查询方法,您可以这样做:

def states
  [ :initial, :active, :inactive ]
end

def self.included(Model)
  states = Model.new.states
  states.each do |state|
  base.send(:define_method, "#{state}?") do
    self.state == state
end

因此,为了加载资源,我们需要实例化模型(Model.new 行)。为了解决这个问题,我们将其更改为:

def self.states
  [ :initial, :active, :inactive ]
end

def self.included(Model)
  states = Model.states
  states.each do |state|
  base.send(:define_method, "#{state}?") do
    self.state == state
end

希望这对某人有帮助!

于 2015-01-28T01:35:20.123 回答
2

这是使用 ActiveRecord 时的常见问题,您不是第一个遇到此错误的人!这很常见,我们在上面写了一个文档:https ://circleci.com/docs/ruby-exception-during-schema-load

于 2013-10-02T20:36:06.220 回答