2009-10-27 5 views
41

У меня есть следующая миграция, и я хочу, чтобы проверить, является ли текущая база данных, относящаяся к среде, базой данных mysql. Если это mysql, то я хочу выполнить SQL, специфичный для базы данных.Как проверить тип базы данных в миграции Rails?

Как это сделать?

 
class AddUsersFb < ActiveRecord::Migration 

    def self.up 
    add_column :users, :fb_user_id, :integer 
    add_column :users, :email_hash, :string 
    #if mysql 
    #execute("alter table users modify fb_user_id bigint") 
    end 

    def self.down 
    remove_column :users, :fb_user_id 
    remove_column :users, :email_hash 
    end 

end 

ответ

37

ActiveRecord::Base.connection предоставит вам все, что вы когда-либо хотели знать о подключении к базе данных, установленной boot.rb и environment.rb

ActiveRecord::Base.connection возвращает много информации , Итак, вы должны точно знать, что вы ищете.

Как Marcel указывает:

ActiveRecord::Base.connection.instance_of? 
    ActiveRecord::ConnectionAdapters::MysqlAdapter 

, вероятно, лучший способ определения, если ваш MySQL базы данных.

Несмотря опираясь на внутреннюю информацию, которая может изменить между ActiveRecord выпуска, я предпочитаю делать это так:

ActiveRecord::Base.connection.instance_values["config"][:adapter] == "mysql" 
+1

'ActiveRecord :: Base.connection.instance_of? ActiveRecord :: ConnectionAdapters :: MysqlAdapter' должен решить эту проблему. –

-4

Это может помочь:

execute 'alter table users modify fb_user_id bigint WHERE USER() = "mysqluser";'

+1

Он не будет работать, когда пользователь индивидуален и не будут работать какие-либо базы данных, где 'USER()' функция не определена, для например SQLite. –

55

Еще более короткий вызов

ActiveRecord::Base.connection.adapter_name == 'MySQL' 
+6

Я использую gem mysql2, и я подозреваю, что некоторые другие могут на этом этапе, поэтому я использую следующее: 'ActiveRecord :: Base.connection.adapter_name.downcase.starts_with? 'mysql'' – bensnider

+5

'ActiveRecord :: Base.connection.adapter_name ==« Mysql2 »' работал для меня с Rails 4. – Jason

8

В Rails 3, (возможно раньше, но Я использую Rails 3 в настоящее время) с помощью ActiveRecord :: ConnectionAdapters :: MysqlAdapter - это плохой способ, потому что он инициализируется только в том случае, если используется адаптер базы данных MySQL. Даже если у вас установлен камень MySQL, если это не ваш тип соединения, то вызов Виль неудачу:

Loading development environment (Rails 3.0.3) 
>> ActiveRecord::Base.connection.instance_of? ActiveRecord::ConnectionAdapters::MysqlAdapter 
NameError: uninitialized constant ActiveRecord::ConnectionAdapters::MysqlAdapter 
from (irb):1 

Таким образом, я бы рекомендовал ответ stasl и использовать adapter_name свойство соединения.

25

Существует adapter_name в AbstractAdapter, и это существует с тех пор, как Rails2.

Так что проще использовать в миграции, как это:

adapter_type = connection.adapter_name.downcase.to_sym 
case adapter_type 
when :mysql 
    # do the MySQL part 
when :sqlite 
    # do the SQLite3 part 
when :postgresql 
    # etc. 
else 
    raise NotImplementedError, "Unknown adapter type '#{adapter_type}'" 
end 
+2

Это не будет работать с gem mysql2 - вы можете просто отредактировать строку, которая будет '' 'когда : mysql,: mysql2'''. – mrm

+0

Ваш ответ более полный и чистый. Благодарю. – cassioscabral

+0

Для postgres: ' def is_postgres? name = ActiveRecord :: Base.connection.adapter_name.downcase name = ~/postgres/ конец ' – Blaskovicz

Смежные вопросы