2009-10-27 9 views
41

Ho la seguente migrazione e voglio essere in grado di verificare se il database corrente relativo all'ambiente è un database mysql. Se è mysql allora voglio eseguire l'SQL che è specifico per il database.Come posso controllare il tipo di database in una migrazione di Rails?

Come faccio a fare questo?

 
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 

risposta

37

ActiveRecord::Base.connection vi fornirà tutto quello che avreste sempre voluto sapere sul collegamento banca dati costituita dalla boot.rb e environment.rb

ActiveRecord::Base.connection restituisce un sacco di informazioni . Quindi devi sapere esattamente cosa stai cercando.

Come Marcel sottolinea:

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

è probabilmente il miglior metodo per determinare se il database MySQL.

Nonostante basandosi su informazioni interne che potrebbe cambiare tra ActiveRecord rilascio, preferisco farlo in questo modo:

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

'ActiveRecord :: Base.connection.instance_of? ActiveRecord :: ConnectionAdapters :: MysqlAdapter' dovrebbe risolverlo. –

-4

Questo potrebbe aiutare:

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

+1

Non funzionerà quando l'utente è diverso e non funzionerà alcun database dove 'utente()' non è definita la funzione, per per esempio SQLite. –

55

Ancora più chiamata più breve

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

Sto usando la gemma mysql2 e sospetto che altri potrebbero a questo punto, quindi uso quanto segue: 'ActiveRecord :: Base.connection.adapter_name.downcase.starts_with? 'mysql'' – bensnider

+5

'ActiveRecord :: Base.connection.adapter_name ==" Mysql2 "' ha funzionato per me con Rails 4. – Jason

8

In Rails 3, (forse in precedenza, ma Attualmente sto usando Rails 3) usando ActiveRecord :: ConnectionAdapters :: MysqlAdapter è un modo scarso di procedere, poiché è solo inizializzato se l'adattatore del database in uso è MySQL. Anche se avete la gemma MySQL installato, se non è il tipo di connessione, quella chiamata wil fallire:

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

Quindi, io consiglierei la risposta di stasl e utilizzare la proprietà adapter_name della connessione.

25

C'è un adapter_name in AbstractAdapter e che è lì da Rails2.

così è più facile da utilizzare per la migrazione in questo modo:

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

Questo non funzionerà con la gemma mysql2-puoi semplicemente modificare la riga per essere '' 'quando : mysql,: mysql2'''. – mrm

+0

La tua risposta è più completa e pulita. Grazie. – cassioscabral

+0

Per postgres: ' def is_postgres? name = ActiveRecord :: Base.connection.adapter_name.downcase nome = ~/postgres/ fine ' – Blaskovicz

Problemi correlati