1

I wrote a migration with the following (create new table named sources):

class CreateSources < ActiveRecord::Migration
  def change
    create_table :sources do |t|
      t.string :name, null: false, default: ""

      t.timestamps null: false
    end
  end
end

And then I modified my existing model :

class Property < ActiveRecord::Base
  validates :source, allow_blank: true, inclusion: { in: 
  Source.all.map{ |source| source.name } }

I want to add validation to the property's source to only allow source from sources table.

And then when I run the migration, I got the following error:

ActiveRecord::StatementInvalid: Mysql2::Error: Table 'sources' doesn't exist: SELECT `sources`.* FROM `sources`

The problem is query of source table is occured when it hasn't been initialized yet.
Any tips on how I can get the migration to run?
This is run on production level. so I might can't drop all the migration and rearrange it.

Rails version 4.2.5
SQL version 5.7

2 Answers 2

1

Keep in mind that your Source.all.map{ |source| source.name } is going to be executed when the Property class is being loaded. The Source class might not be properly initialized at that point and there might not be a proper database connection set up. Also, you'll only access Source.all once so you'd have to restart your app if you added a new Source.

Instead, validate by hand:

class Property < ActiveRecord::Base
  validate :valid_source
private
  def valid_source
    return if(source.blank?)
    return if(Source.where(name: source).exists?)
    errors.add(:source, 'Unknown source') # Or whatever you want to say
  end
end

That way you're checking the sources table at the right time.

Also, I wouldn't expect the error you're seeing to occur in a migration. Perhaps you're using a model inside a migration, that is to be avoided.

As an aside, is there particular reason that you don't have belongs_to :source instead? Copying the name around like that is very error prone, using a reference (hopefully backed by a foreign key in the database) would be much safer.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much. It's working now!! And also may I know how to check if I using model inside a migration? Seems like I don't do it, but it's occured.
To check the migrations you'd have to look at them by hand or search them. You might also want to check your initializers to see if they're up to anything.
0

Have you defined Source model? I hope so.

Here the problem looks like the loading of Property class takes priority before migration is run and hence the issue.

1 Comment

Yes I've defined it. And also Property migration is above Source migration.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.