Comment écrire SQL dans une migration en Rails

j'ai le code SQL suivant lequel j'ai besoin de faire

CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;

DROP TABLE cars_users;

ALTER TABLE cars_users2 RENAME TO cars_users;

comme je ne peux pas utiliser heroku dataclips pour déposer une table, Je ne peux pas utiliser dataclips.

Donc je suppose que j'ai besoin de faire une migration.

Comment puis-je écrire ce sql en tant que migration?

45
demandé sur user2262149 2013-02-13 19:23:08

4 réponses

Pour votre migration:

execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;" 
drop_table :car_users  
rename_table :car_users2, :car_users  

et pour le bas:

raise ActiveRecord::IrreversibleMigration

migration complète:

class TheMigration < ActiveRecord::Migration
    def up
        execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * from cars_users;" 
        drop_table :car_users  
        rename_table :car_users2, :car_users  
    end

    def down
        raise ActiveRecord::IrreversibleMigration
    end
end
88
répondu Tomdarkness 2016-03-20 11:36:52

Vous pouvez essayer d'utiliser le execute méthode.

quelque Chose comme ça (c'est pas testé, une sorte de fruit)

class UpdateCarUserTable < ActiveRecord::Migration
  def up
    execute "CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users"
    execute "DROP TABLE cars_users"
    execute "ALTER TABLE cars_users2 RENAME TO cars_users"
  end

Comme il n'y a pas d'équivalent down méthode ActiveRecord::IrreversibleMigration doit être augmenté en essayant de migrer vers le bas.

16
répondu ConcurrentHashMap 2016-03-20 11:00:35

je préfère ici doc:

execute <<-SQL
  CREATE TABLE cars_users2 AS SELECT DISTINCT * FROM cars_users;
  DROP TABLE cars_users;
  ALTER TABLE cars_users2 RENAME TO cars_users;
SQL

avis: Cela ne fonctionne que pour PostgreSQL, si vous utilisez MySQL vous devez définir statements CLIENT_MULTI_STAT pour l'adaptateur.

3
répondu fangxing 2017-03-24 04:54:56

dans le cas où vous devez utiliser change au lieu de up et down vous pouvez utiliser reversible. Il fonctionne sur les Rails 4 ou plus.

class ExampleMigration < ActiveRecord::Migration
  def change
    create_table :distributors do |t|
      t.string :zipcode
    end

    reversible do |dir|
      dir.up do
        # add a CHECK constraint
        execute <<-SQL
          ALTER TABLE distributors
            ADD CONSTRAINT zipchk
              CHECK (char_length(zipcode) = 5) NO INHERIT;
        SQL
      end
      dir.down do
        execute <<-SQL
          ALTER TABLE distributors
            DROP CONSTRAINT zipchk
        SQL
      end
    end

    add_column :users, :home_page_url, :string
    rename_column :users, :email, :email_address
  end
end

Sources: http://edgeguides.rubyonrails.org/active_record_migrations.html#using-reversible

https://apidock.com/rails/ActiveRecord/Migration/reversible

3
répondu João Paulo Motta 2017-05-03 23:10:35