Using Active Records In Migrations

Not sure if this is a bug or by design. But I am unable to use an active record model in a migration against the non default database

I’m trying to run the migrations against a test database. But if I call


new MyModel()

or


MyModel::model()

The model always uses the default database, not the database provided with


yiic migrate --connectionID=testdb

I’m thinking you’re not supposed to use active records in migrations by use the provided SQL query help functions?

But I found this post http://www.yiiframework.com/forum/index.php/topic/15905-test-data-in-db-migration/page__p__78981#entry78981 that seems to suggest that using an active record in a migration is fine?

[size=2]Your test database have a same tables which you are using in your development database.[/size]

Since, MyModel class related table is present in your dev database. And please also check console.php database settings which database you are accessing there.

It’s by design. You should never use model in migrations since model code can be changed slightly while one should be able to run migrations from the very first (where model was different) to the current.

1 Like

Cheers, that makes sense.

That was the conclusion I was coming to.

Time to fix up my migrations.

Two questions here:

  1. How to import model to migration, when (temporarily) ignoring your advice? Neither this:

Yii::import('application.models.*');


echo Content::CONTENT_STATUS_CLOSED;

nor that:


Yii::import('application.models.Content');


echo Content::CONTENT_STATUS_CLOSED;

works:


PHP Error[2]: include(C:\XAMPP\websites\website\protected\models\Content.php):

failed to open stream: No such file or directory

	in file C:\XAMPP\websites\yii\framework\YiiBase.php at line 404

  1. Following previous one. How to deal with the situation like above, that you have a constant defined in your model and you want to use it in migration?

I’ve solved above with:


require_once dirname(__FILE__).'/../models/data/Content.php';

But this looks like a pretty ugly way of doing this. Is there a better way?

Why shooting yourself in a leg when you were warned?