palkan / logidze

Database changes log for Rails

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Logidze.ignore_log_data_by_default causing db:migrate errors

matgaw opened this issue · comments

Tell us about your environment

**Ruby Version:3.0.5

**Rails Version:7.0.4

**PostgreSQL Version:14

**Logidze Version:1.2.2

What did you do?

Added config/initializers/logidze.rb with following code to my project:
Logidze.ignore_log_data_by_default = true

What did you expect to happen?

Test suite still passing

What actually happened?

I started to get errors during db:migrate related to a situation where:

  • one migration adds a column to some model - let's say adds some_column to SomeModel
  • second migration removes this column from SomeModel
  • third migration is executing code like:
def change
    SomeModel.all.each {
    [...]

then I get error such like:
PG::UndefinedColumn: ERROR: column some_model.some_column does not exist

This is weird, because at the point of third migration, Rails shouldn't refer the already-removed some_column. Please note that there's no reference to some_column in the entire app code - except for old migrations that add and remove this column (but they don't do anything else with it).

This error goes away if I remove ignore_log_data_by_default = true from initializers.

I think that this setting somehow messes with migration code and causes Rails to still expect this column to be a part of the model.

Current workaround - instead of adding this setting to config/initializers/logidze.rb - add the following to config/application.rb:

config.after_initialize do
      # disable loading of log data by default
      # this needs to stay enabled if we are inside Rake task (e.g. during a migration), because otherwise it creates
      # errors with ActiveRecord trying to reach non-existent columns - hence the if below
      # note that this can't be moved to config/initializers because it's too early there to detect if we're inside
      # a Rake task
      if Rake.application.rakefile.blank?
        Logidze.ignore_log_data_by_default = true
      end
    end

This is weird, because at the point of third migration, Rails shouldn't refer the already-removed some_column.

Maybe, it's not that weird as it seems. Rails keeps the database schema in a cache (you can reset it by running SomeColumn.reset_column_information). The reason why it's affected by the ignore_log_data_by_default setting is as follows: when a table has ignored columns, Active Record always uses an explicit list of columns to fetch instead of SELECT *; thus, it adds a no-longer-existing column to the list and fails. If you don't have any ignored columns, Rails uses SELECT * and everything works fine.

So, it's not really related to Logidze, but the way ignored_columns works.