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.
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.
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.
精彩评论