48

I have the following migration and I want to be able to check if the current database related to the environment is a mysql database. If it's mysql then I want to execute the SQL that is specific to the database.

How do I go about this?

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
mu is too short
  • 426,620
  • 70
  • 833
  • 800
Shaun
  • 4,057
  • 7
  • 38
  • 48

5 Answers5

60

Even more shorter call

ActiveRecord::Base.connection.adapter_name == 'MySQL'
stasl
  • 953
  • 7
  • 6
  • 7
    I'm using the mysql2 gem, and I suspect some others might at this point, so I use the following: `ActiveRecord::Base.connection.adapter_name.downcase.starts_with? 'mysql'` – bensnider Jan 11 '13 at 21:03
  • 6
    `ActiveRecord::Base.connection.adapter_name == "Mysql2"` worked for me with Rails 4. – Jason Aug 05 '13 at 21:12
46

ActiveRecord::Base.connection will provide you with everything you ever wanted to know about the database connection established by boot.rb and environment.rb

ActiveRecord::Base.connection returns a lot of information. So you've got to know exactly what you're looking for.

As Marcel points out:

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

is probably the best method of determining if your database MySQL.

Despite relying on internal information that could change between ActiveRecord release, I prefer doing it this way:

ActiveRecord::Base.connection.instance_values["config"][:adapter] == "mysql"
Vadim K.
  • 2,370
  • 18
  • 26
EmFi
  • 23,435
  • 3
  • 57
  • 68
29

There is an adapter_name in AbstractAdapter and that is there since Rails2.

So it's easier to use in the migration like this:

adapter_type = connection.adapter_name.downcase.to_sym
case adapter_type
when :mysql, :mysql2
  # do the MySQL part
when :sqlite
  # do the SQLite3 part
when :postgresql
  # etc.
else
  raise NotImplementedError, "Unknown adapter type '#{adapter_type}'"
end
KARASZI István
  • 30,900
  • 8
  • 101
  • 128
8

In Rails 3, (maybe earlier, but I'm using Rails 3 currently) using ActiveRecord::ConnectionAdapters::MysqlAdapter is a poor way to go about it, as it's only initialized if the database adapter in use is MySQL. Even if you have the MySQL gem installed, if it's not your connection type, that call wil fail:

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, I'd recommend stasl's answer and use the adapter_name property of the connection.

ctide
  • 5,217
  • 1
  • 29
  • 26
-4

This might help:

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

CodeJoust
  • 3,760
  • 21
  • 23
  • 1
    It won't work when the user is different and won't work any databases where `USER()` function is not defined, for e.g. SQLite. – KARASZI István Apr 20 '11 at 10:55