可以在ActiveRecord :: Migration中使用基类吗?

时间:2009-11-09 02:06:14

标签: ruby-on-rails inheritance activerecord

如果我的模型看起来像这样:

(app/models/letter.rb)
class Letter < ActiveRecord::Base
  def cyrilic_equivilent
    # return somethign similar
  end
end

class A < Letter
end

class B < Letter
end

我的迁移是否也遵循这种模式:

class CreateLetter < ActiveRecord::Migration
  def self.up
    create_table :letters do |t|
      t.timestamps
    end
  end
end

class CreateA < CreateLetter
end

class CreateB < CreateLetter
end

3 个答案:

答案 0 :(得分:1)

当然可以......你的目标是什么?你需要声明

class CreateA < CreateLetter

答案 1 :(得分:1)

你要做的事情根本不起作用。

运行迁移时,Rails运行up类方法。让新的迁移继承另一个迁移的up方法将尝试创建两次相同的表。这将导致迁移失败。

并不重要。由于迁移的工作方式,Rails只会运行与包含它的文件共享其名称的类。

看起来你正在尝试做两件类似的事情之一。

  1. 模型建议单表继承。 STI需要一个名为type的字符串列,所有子类都将使用父模型的表,在本例中为字母。您只需要定义一个表,并且当将一个模型声明为另一个模型的子类时,Rails会处理所有类型列的谜团。

  2. 您正在尝试定义多个类似的表,然后调整差异。这可以通过单次迁移中的循环和条件来完成。但是,您需要在从其他模型继承的任何模型中定义table_name以禁用隐含的单表继承。你的迁移循环会像这样:

    class CreateLetter < ActiveRecord::Migration
      def self.up
        [:letters, :a, :b].each do |table_name|
          create_table table_name do |t|
          ...
          t.timestamps
    
             if table_name == :a
               # columns only in table a
             end
    
             if table_name == :b
               # columns only in table b
             end        
           end
         end
    end
    

答案 2 :(得分:1)

我在ActiveRecord 3.0.3中进行了迁移

class BaseMigration < ActiveRecord::Migration
   def self.create_base_columns(tbl)
     tbl.string :some_reused_field
   end
end

class AnotherMigration < BaseMigration
  def self.up 
     create_table(:sometable) do |t|
     create_base_columns(t)
  end
end

更新到3.2.3之后我不断发现'方法缺失:create_table',所以我不得不改为:

module BaseMigration
  def create_base_columns(tbl)
     tbl.string :some_reused_field
  end
end

class AnotherMigration < ActiveRecord::Migration
  extend BaseMigration
  def self.up 
    create_table(:sometable) do |t|
      create_base_columns(t)
    end
  end
end

我会认为这些是等价的,但由于某种原因,AR不再允许我使用继承。

注意:任何一种方法 都可以在3.0.3上工作,但只能扩展模块3.2.3

当我有时间时,我想在准确的轨道应用程序上尝试这个。