开发者

Possible to use a base class with ActiveRecord::Migration?

If my models look like this:

(app/models/letter.rb)
class Letter < ActiveRecord::Base
  def cyrilic_equivilent
    # return somethign sim开发者_如何学Pythonilar
  end
end

class A < Letter
end

class B < Letter
end

Can my migrations also follow this pattern:

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


What you're trying to do won't work at all.

When a migration is run, Rails runs the up class method. Having a new migration inherit another migration's up method will try to create the same table twice. This will cause the migration to fail.

Not that it matters any way. Due to the way that migrations work Rails will only run the class that shares its name with the file that contains it.

It looks like you're trying to do one of two similar things here.

  1. The models suggest Single Table Inheritance. STI requires a string column named type and all subclasses will use the table of the parent model, in this case letters. You only need to define one table, and Rails takes care of all the type column mysteries when declare one model to be a subclass of another.

  2. You're trying to define multiple similar tables and then tweak the differences. This can be done with loops and conditions in a single migration. However you will need to need to define the table_name in any of the models that are inheriting from others to disable the implied Single Table Inheritance. Your migration loop would like something like this:

    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
    


Certainly can...what's your goal here? You would need to declare

class CreateA < CreateLetter


I was doing this with a migration in 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

After Updating to 3.2.3 I keep getting 'method missing :create_table', so I had to change to:

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

I would have assumed these to be equivalent, but for some reason AR no longer lets me use inheritance.

NOTE: that either method does work on 3.0.3 but only extending the module worked on 3.2.3

When I have time I'd like to try this on a barebones rails app.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜