ActiveRecord migration on specific database connection can't rollback











up vote
0
down vote

favorite












TL;DR - Using an explicit database connection in a migration breaks reversibility.



I have a simple migration, adding a column to a specific database connection: (My app has several databases, for good reasons)



class AddFlavorToBikes < ActiveRecord::Migration
def change
VehicleBase.connection.tap do |db|
db.add_column :bikes, :flavor, :string
end
end
end


This works great:



 % be rake db:migrate
== 20181120215337 AddFlavorToBikes: migrating =================================
== 20181120215337 AddFlavorToBikes: migrated (0.0060s) ========================


However, it fails to rollback:



% be rake db:rollback
== 20181120215337 AddFlavorToBikes: reverting =================================
rake aborted!
An error has occurred, this and all later migrations canceled:

PG::DuplicateColumn: ERROR: column "flavor" of relation "bikes" already exists
: ALTER TABLE "bikes" ADD "flavor" character varying/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:5:in `block in change'
/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `tap'
/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `change'


I don't understand this. The rollback of db.add_column should remove the column. So why am I getting an error that the field I'm trying to remove already exists? Of course it exists, that's why I'm trying to remove it.



I searched the Interwebs for a solution, or even anyone with the same problem, and did not find any leads.



I tried using an explicit variable instead of .tap, but got the same error:



class AddFlavorToBikes < ActiveRecord::Migration
def change
db = VehicleBase.connection
db.add_column :bikes, :flavor, :string
end
end


The closest I've been able to discern, ActiveRecord::Migration loses its ability to detect if it is migrating up or down on any but the default ActiveRecord::Base connection.



So, it tries to migrate add_column UP, even though it is in a rollback and should be migrating it DOWN. Hence, it is trying to add the column a second time, instead of reversing the add_column into a remove_column.



This is on Rails 4.2.7 and Ruby 2.1.9



How can I make this migration reversible?










share|improve this question


























    up vote
    0
    down vote

    favorite












    TL;DR - Using an explicit database connection in a migration breaks reversibility.



    I have a simple migration, adding a column to a specific database connection: (My app has several databases, for good reasons)



    class AddFlavorToBikes < ActiveRecord::Migration
    def change
    VehicleBase.connection.tap do |db|
    db.add_column :bikes, :flavor, :string
    end
    end
    end


    This works great:



     % be rake db:migrate
    == 20181120215337 AddFlavorToBikes: migrating =================================
    == 20181120215337 AddFlavorToBikes: migrated (0.0060s) ========================


    However, it fails to rollback:



    % be rake db:rollback
    == 20181120215337 AddFlavorToBikes: reverting =================================
    rake aborted!
    An error has occurred, this and all later migrations canceled:

    PG::DuplicateColumn: ERROR: column "flavor" of relation "bikes" already exists
    : ALTER TABLE "bikes" ADD "flavor" character varying/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:5:in `block in change'
    /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `tap'
    /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `change'


    I don't understand this. The rollback of db.add_column should remove the column. So why am I getting an error that the field I'm trying to remove already exists? Of course it exists, that's why I'm trying to remove it.



    I searched the Interwebs for a solution, or even anyone with the same problem, and did not find any leads.



    I tried using an explicit variable instead of .tap, but got the same error:



    class AddFlavorToBikes < ActiveRecord::Migration
    def change
    db = VehicleBase.connection
    db.add_column :bikes, :flavor, :string
    end
    end


    The closest I've been able to discern, ActiveRecord::Migration loses its ability to detect if it is migrating up or down on any but the default ActiveRecord::Base connection.



    So, it tries to migrate add_column UP, even though it is in a rollback and should be migrating it DOWN. Hence, it is trying to add the column a second time, instead of reversing the add_column into a remove_column.



    This is on Rails 4.2.7 and Ruby 2.1.9



    How can I make this migration reversible?










    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      TL;DR - Using an explicit database connection in a migration breaks reversibility.



      I have a simple migration, adding a column to a specific database connection: (My app has several databases, for good reasons)



      class AddFlavorToBikes < ActiveRecord::Migration
      def change
      VehicleBase.connection.tap do |db|
      db.add_column :bikes, :flavor, :string
      end
      end
      end


      This works great:



       % be rake db:migrate
      == 20181120215337 AddFlavorToBikes: migrating =================================
      == 20181120215337 AddFlavorToBikes: migrated (0.0060s) ========================


      However, it fails to rollback:



      % be rake db:rollback
      == 20181120215337 AddFlavorToBikes: reverting =================================
      rake aborted!
      An error has occurred, this and all later migrations canceled:

      PG::DuplicateColumn: ERROR: column "flavor" of relation "bikes" already exists
      : ALTER TABLE "bikes" ADD "flavor" character varying/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:5:in `block in change'
      /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `tap'
      /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `change'


      I don't understand this. The rollback of db.add_column should remove the column. So why am I getting an error that the field I'm trying to remove already exists? Of course it exists, that's why I'm trying to remove it.



      I searched the Interwebs for a solution, or even anyone with the same problem, and did not find any leads.



      I tried using an explicit variable instead of .tap, but got the same error:



      class AddFlavorToBikes < ActiveRecord::Migration
      def change
      db = VehicleBase.connection
      db.add_column :bikes, :flavor, :string
      end
      end


      The closest I've been able to discern, ActiveRecord::Migration loses its ability to detect if it is migrating up or down on any but the default ActiveRecord::Base connection.



      So, it tries to migrate add_column UP, even though it is in a rollback and should be migrating it DOWN. Hence, it is trying to add the column a second time, instead of reversing the add_column into a remove_column.



      This is on Rails 4.2.7 and Ruby 2.1.9



      How can I make this migration reversible?










      share|improve this question













      TL;DR - Using an explicit database connection in a migration breaks reversibility.



      I have a simple migration, adding a column to a specific database connection: (My app has several databases, for good reasons)



      class AddFlavorToBikes < ActiveRecord::Migration
      def change
      VehicleBase.connection.tap do |db|
      db.add_column :bikes, :flavor, :string
      end
      end
      end


      This works great:



       % be rake db:migrate
      == 20181120215337 AddFlavorToBikes: migrating =================================
      == 20181120215337 AddFlavorToBikes: migrated (0.0060s) ========================


      However, it fails to rollback:



      % be rake db:rollback
      == 20181120215337 AddFlavorToBikes: reverting =================================
      rake aborted!
      An error has occurred, this and all later migrations canceled:

      PG::DuplicateColumn: ERROR: column "flavor" of relation "bikes" already exists
      : ALTER TABLE "bikes" ADD "flavor" character varying/Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:5:in `block in change'
      /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `tap'
      /Users/david/rider-gate/db/migrate/20181120215337_add_flavor_to_bikes.rb:3:in `change'


      I don't understand this. The rollback of db.add_column should remove the column. So why am I getting an error that the field I'm trying to remove already exists? Of course it exists, that's why I'm trying to remove it.



      I searched the Interwebs for a solution, or even anyone with the same problem, and did not find any leads.



      I tried using an explicit variable instead of .tap, but got the same error:



      class AddFlavorToBikes < ActiveRecord::Migration
      def change
      db = VehicleBase.connection
      db.add_column :bikes, :flavor, :string
      end
      end


      The closest I've been able to discern, ActiveRecord::Migration loses its ability to detect if it is migrating up or down on any but the default ActiveRecord::Base connection.



      So, it tries to migrate add_column UP, even though it is in a rollback and should be migrating it DOWN. Hence, it is trying to add the column a second time, instead of reversing the add_column into a remove_column.



      This is on Rails 4.2.7 and Ruby 2.1.9



      How can I make this migration reversible?







      ruby-on-rails activerecord migration rollback






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 2 days ago









      David Hempy

      884925




      884925
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          2
          down vote













          I found a reasonable solution by splitting change into up and down methods:



          class AddFlavorToBikes < ActiveRecord::Migration
          def up
          VehicleBase.connection.tap do |db|
          db.add_column :bikes, :flavor, :string
          end
          end

          def down
          VehicleBase.connection.tap do |db|
          db.remove_column :bikes, :flavor
          end
          end
          end


          While not as graceful or DRY as a reversible migration, this allows db:migrate and db:rollback to work succesfully.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402734%2factiverecord-migration-on-specific-database-connection-cant-rollback%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            2
            down vote













            I found a reasonable solution by splitting change into up and down methods:



            class AddFlavorToBikes < ActiveRecord::Migration
            def up
            VehicleBase.connection.tap do |db|
            db.add_column :bikes, :flavor, :string
            end
            end

            def down
            VehicleBase.connection.tap do |db|
            db.remove_column :bikes, :flavor
            end
            end
            end


            While not as graceful or DRY as a reversible migration, this allows db:migrate and db:rollback to work succesfully.






            share|improve this answer

























              up vote
              2
              down vote













              I found a reasonable solution by splitting change into up and down methods:



              class AddFlavorToBikes < ActiveRecord::Migration
              def up
              VehicleBase.connection.tap do |db|
              db.add_column :bikes, :flavor, :string
              end
              end

              def down
              VehicleBase.connection.tap do |db|
              db.remove_column :bikes, :flavor
              end
              end
              end


              While not as graceful or DRY as a reversible migration, this allows db:migrate and db:rollback to work succesfully.






              share|improve this answer























                up vote
                2
                down vote










                up vote
                2
                down vote









                I found a reasonable solution by splitting change into up and down methods:



                class AddFlavorToBikes < ActiveRecord::Migration
                def up
                VehicleBase.connection.tap do |db|
                db.add_column :bikes, :flavor, :string
                end
                end

                def down
                VehicleBase.connection.tap do |db|
                db.remove_column :bikes, :flavor
                end
                end
                end


                While not as graceful or DRY as a reversible migration, this allows db:migrate and db:rollback to work succesfully.






                share|improve this answer












                I found a reasonable solution by splitting change into up and down methods:



                class AddFlavorToBikes < ActiveRecord::Migration
                def up
                VehicleBase.connection.tap do |db|
                db.add_column :bikes, :flavor, :string
                end
                end

                def down
                VehicleBase.connection.tap do |db|
                db.remove_column :bikes, :flavor
                end
                end
                end


                While not as graceful or DRY as a reversible migration, this allows db:migrate and db:rollback to work succesfully.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 2 days ago









                David Hempy

                884925




                884925






























                     

                    draft saved


                    draft discarded



















































                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53402734%2factiverecord-migration-on-specific-database-connection-cant-rollback%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Berounka

                    Different font size/position of beamer's navigation symbols template's content depending on regular/plain...

                    Sphinx de Gizeh