2009-10-27 4 views
41

Mam następującą migrację i chcę móc sprawdzić, czy bieżąca baza danych związana z środowiskiem jest bazą danych mysql. Jeśli jest to mysql, to chcę wykonać SQL, który jest specyficzny dla bazy danych.Jak sprawdzić typ bazy danych w migracji Rails?

Jak mogę to zrobić?

 
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 

Odpowiedz

37

ActiveRecord::Base.connection dostarczy Ci wszystkiego, co kiedykolwiek chciałeś wiedzieć o połączenia z bazą danych ustanowionego przez boot.rb i environment.rb

ActiveRecord::Base.connection zwraca dużo informacji . Więc musisz dokładnie wiedzieć, czego szukasz.

Jak Marcel zaznacza:

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

jest prawdopodobnie najlepszym sposobem określenia, czy swojej bazy danych MySQL.

Pomimo powołując się na wewnętrznych informacji, które mogłyby zmienić między ActiveRecord wydaniu, wolę robić to w ten sposób:

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

'ActiveRecord :: Base.connection.instance_of? ActiveRecord :: ConnectionAdapters :: MysqlAdapter' powinien go rozwiązać. –

-4

To może pomóc:

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

+1

To nie będzie działać, gdy użytkownik jest inny i nie będzie działać żadnych baz danych, gdzie 'USER()' funkcja nie jest zdefiniowana, dla na przykład SQLite. –

55

Jeszcze krótsze połączenia

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

Używam klejnotu mysql2 i podejrzewam, że niektóre inne mogą w tym momencie, więc używam następujących: 'ActiveRecord :: Base.connection.adapter_name.downcase.starts_with? 'mysql'' – bensnider

+5

'ActiveRecord :: Base.connection.adapter_name ==" Mysql2 "' pracował dla mnie z Rails 4. – Jason

8

W Rails 3, (być może wcześniej, ale Używam Rails 3 obecnie) przy użyciu ActiveRecord :: ConnectionAdapters :: MysqlAdapter jest kiepskim sposobem, aby go przejść, ponieważ jest inicjowany tylko wtedy, gdy używany adapter bazy danych jest MySQL. Nawet jeśli masz zainstalowany gem MySQL, jeśli nie jest to typ połączenia, że ​​wezwanie nie wil:

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

Więc polecam odpowiedź stasl i użyć właściwości ADAPTER_NAME połączenia.

25

Istnieje adapter_name w AbstractAdapter i jest tam od Rails2.

więc łatwiej jest używać w migracji tak:

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

To nie zadziała z gemem mysql2 - możesz po prostu edytować linię, aby była '' ', gdy : mysql,: mysql2'''. – mrm

+0

Twoja odpowiedź jest bardziej kompletna i czysta. Dzięki. – cassioscabral

+0

Dla postgresów: ' def is_postgres? name = ActiveRecord :: Base.connection.adapter_name.downcase name = ~/postgres/ koniec ' – Blaskovicz