2009-10-27 2 views
41

Ich habe die folgende Migration und ich möchte in der Lage sein zu überprüfen, ob die aktuelle Datenbank in Bezug auf die Umgebung eine MySQL-Datenbank ist. Wenn es mysql ist, dann möchte ich das SQL ausführen, das spezifisch für die Datenbank ist.Wie überprüfe ich den Datenbanktyp in einer Rails Migration?

Wie gehe ich vor?

 
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 

Antwort

37

ActiveRecord::Base.connection werden Sie mit allem, was Sie jemals über die Datenbankverbindung hergestellt von boot.rb und environment.rb

ActiveRecord::Base.connection gibt eine Menge Informationen wissen wollten . Sie müssen also genau wissen, wonach Sie suchen.

Wie Marcel betont:

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

ist wahrscheinlich die beste Methode, wenn Ihre Datenbank MySQL zu bestimmen.

Trotz auf interne Informationen verlassen, die zwischen ActiveRecord Release ändern könnten, ziehe ich es auf diese Weise tun:

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

'ActiveRecord :: Base.connection.instance_of? ActiveRecord :: ConnectionAdapters :: MysqlAdapter' sollte es lösen. –

-4

Dies könnte helfen:

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

+1

Es wird nicht funktionieren, wenn der Benutzer unterschiedlich ist und keine Datenbanken arbeiten, wo 'USER()' Funktion nicht definiert ist, für z.B SQLite. –

55

Noch kürzer Anruf

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

Ich benutze das mysql2-Juwel, und ich vermute, einige andere könnten an dieser Stelle, also verwende ich Folgendes: 'ActiveRecord :: Base.connection.adapter_name.downcase.starts_with? 'mysql'' – bensnider

+5

'ActiveRecord :: Base.connection.adapter_name ==" Mysql2 "' funktionierte für mich mit Rails 4. – Jason

8

In Rails 3, (vielleicht früher, aber Ich verwende derzeit Rails 3) mit ActiveRecord :: ConnectionAdapters :: MysqlAdapter ist eine schlechte Möglichkeit, da es nur initialisiert wird, wenn der verwendete Datenbankadapter MySQL ist. Auch wenn Sie die MySQL-Juwel installiert haben, wenn es nicht Ihre Verbindungsart ist, wil, dass Anruf fehlschlagen:

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

So würde ich die Stasi Antwort und verwenden Sie die adapter_name Eigenschaft der Verbindung empfehlen.

25

Es gibt eine adapter_name in AbstractAdapter und das ist da seit Rails2.

So ist es einfacher, in der Migration wie folgt zu verwenden:

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

Dies funktioniert nicht mit dem mysql2-Juwel - Sie können einfach die Zeile bearbeiten, die '' 'ist : mysql,: mysql2'''. – mrm

+0

Ihre Antwort ist vollständiger und sauber. Vielen Dank. – cassioscabral

+0

Für Postgres: ' def is_postgres? name = ActiveRecord :: Base.connection.Adapter_name.downcase name = ~/postgres/ Ende ' – Blaskovicz