Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails/BulkChangeTable and remove_column #161

Open
6temes opened this issue Jun 14, 2018 · 10 comments
Open

Rails/BulkChangeTable and remove_column #161

6temes opened this issue Jun 14, 2018 · 10 comments

Comments

@6temes
Copy link

6temes commented Jun 14, 2018

This code would trigger Rails/BulkChangeTable

class ChangeACoupleOfColumnsInThing < ActiveRecord::Migration[5.2]
  def change
    remove_column :things, :column_one, :boolean
    add_column    :things, :column_two, :string, null: false, default: ''
  end
end

The problem is that this:

class ChangeACoupleOfColumnsInThing < ActiveRecord::Migration[5.2]
  def change
    change_table :sellers, bulk: true do |t|
      t.remove :column_one, :boolean
      t.column :column_two, :string, null: false, default: ''
    end
  end
end

Will raise RailsReversibleMigration.

Version:

$ rubocop -V
0.57.2
@wata727
Copy link
Contributor

wata727 commented Jun 14, 2018

Maybe you can avoid this offense by writing as follows:

class ChangeACoupleOfColumnsInThing < ActiveRecord::Migration[5.2]
  def change
    reversible do |dir|
      change_table :things, bulk: true do |t|
        dir.up do
          t.remove :column_one
          t.column :column_two, :string, null: false, default: ''
        end

        dir.down do
          t.boolean :column_one # , null: ..., default: ...
          t.remove :column_two
        end
      end
    end
  end
end

But if the time to execute the original two ALTER queries is small enough, this change will be nonsense... Unfortunately, Rails/BulkChangeTable cop can't know the time to execute queries.

Depending on the actual environment, I recommend that you select how to write.

@6temes
Copy link
Author

6temes commented Jun 15, 2018

I don't understand how this Cop can improve my code, though.

@wata727
Copy link
Contributor

wata727 commented Jun 15, 2018

FYI https://aaronlasseigne.com/2012/06/05/faster-activerecord-migrations-using-change-table-bulk/

@6temes
Copy link
Author

6temes commented Jun 15, 2018

んー

So this cop can potentially make some migrations faster for large databases, while introducing some awkwardness in other cases.

I don't know if, with this current behavior, this cop should be activated by default. But it is obviously not to me to choose.

@bbatsov
Copy link
Contributor

bbatsov commented Sep 23, 2018

We're in the process of moving all Rails-related functionality to a standalone library (gem) named rubocop-rails. Please, migrate this issue to its issue tracker https://github.com/rubocop-hq/rubocop-rails/issues/

@bbatsov bbatsov closed this as completed Sep 23, 2018
@louim
Copy link

louim commented Dec 2, 2019

@koic, would you mind moving this issue to the rubocop/rails tracker? I stumbled on this while updating and I think it's an issue that needs to be addressed. Also see: #48 (comment)

I can also open a new issue there, but I would prefer the original issue with the context be moved if you don't mind.

@koic koic transferred this issue from rubocop/rubocop Dec 2, 2019
@koic koic reopened this Dec 2, 2019
@koic
Copy link
Member

koic commented Dec 2, 2019

@louim Thanks for the mention. I transferred this issue to rubocop-hq/rubocop-rails repo.

@louim
Copy link

louim commented Dec 2, 2019

One way to handle the case could be like it was done in #48 and remove the remove_column from the combinable methods.

@thisismydesign
Copy link

Same goes for change_column. I think most projects don't benefit from this and where it actually matters migrations are handled with care. I like @louim's proposal. All methods which are not reversible and lead to more / more complex code should be removed, or the rule should be turned off by default.

leenagupte pushed a commit to alphagov/collections-publisher that referenced this issue Oct 28, 2021
The [original link fields] are used to determine where the action link
text in the header should wrap when the landing page is being viewed in
mobile view.

For example, at the moment the fields contain "Find out how to stay safe
and help" and "prevent the spread". On a desktop this is displayed as
one line "Find out how to stay safe and help prevent the spread", but on
a mobile, it wraps in the expected place.
i.e. the use sees:

 "Find out how to stay safe and help"
 "prevent the spread"

This commit provides two header text fields: `header_link_pre_wrap_text`
and `header_link_post_wrap_text`.

In the migration, I initially wanted to use (header_link_post_wrap_text
omitted from the following examples to save space):

```
  def change
    rename_column :coronavirus_pages, :header_link_text, :header_link_pre_wrap_text
    change_column :coronavirus_pages, :header_link_pre_wrap_text, :string
  end
```

However the linter threw a:

```
Rails/BulkChangeTable: You can use change_table :coronavirus_pages, bulk: true to combine alter queries.
```

error… hence using `bulk: true`.

 ```
  def change
    change_table :coronavirus_pages, bulk: true do |t|
      t.rename :header_link_text, :header_link_pre_wrap_text
      t.string :header_link_pre_wrap_text
    end
  end
 ```

This did not remove the header_link_text and added the
header_link_pre_wrap_text. I decided to remove the column instead:

```
  def change
    change_table :coronavirus_pages, bulk: true do |t|
      t.remove :header_link_text
      t.string :header_link_pre_wrap_text
    end
  end
```

However the linter threw a `Rails/ReversibleMigration` error.

I therefore used `up` and `down` methods to make the migration
reversable, as [suggested by the author of the cop]. Annoyingly
`remove_column` is usually reversible with a `type` but the bulk
[change_table syntax] does not allow a type to be specified.

Its a bit convoluted to appease the linter... it seems to have been
raised as an issue to [Rubocop] but oh well.

[original link fields]: https://github.com/alphagov/govuk-coronavirus-content/blob/12bacb98cdfa9a96a8f6f344143be0be1361babd/content/coronavirus_landing_page.yml#L14-L15
[suggested by the author of the cop]: rubocop/rubocop-rails#110 (comment)
[change_table syntax]: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table
[Rubocop]: rubocop/rubocop-rails#161
@maddog666
Copy link

maddog666 commented Dec 11, 2023

Add type

  def change
    change_table :sellers, bulk: true do |t|
      t.remove :column_one, type: :boolean
      t.column :column_two, :string, null: false, default: ''
    end
  end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants