palkan / logidze

Database changes log for Rails
MIT License
1.59k stars 74 forks source link

Logidze.ignore_log_data_by_default causing db:migrate errors #223

Closed matgaw closed 1 year ago

matgaw commented 1 year ago

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:

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.

matgaw commented 1 year ago

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
palkan commented 1 year ago

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.