palkan / logidze

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

Updating history when column names change #246

Open ScotterC opened 5 months ago

ScotterC commented 5 months ago

This is more an FYI for others and maybe a feature request.

When you change the column name of a logidze backed model, the history won't change the keys to reflect the new column name (I'm not sure it should). It took me a bit of time to figure out a good way to rewrite history so I thought I'd share.

  def convert_keys_in_history(record, old_key, new_key)
    record.reload_log_data
    updated_data = record.log_data.data.deep_dup

    updated_data["h"].each do |elem|
      if elem["c"] && elem["c"][old_key]
        elem["c"][new_key] = elem["c"].delete(old_key)
      end
    end

    record.update_columns(log_data: updated_data)
  end

Post.find_each do |post|
  convert_keys_in_history(post, "old_title_column_name", "new_title_column_name")
end

One might expect history to be immutable so it may not be worth adding functionality to make the above simpler.

palkan commented 5 months ago

I think, having it as a configuration option for has_logidze would be nice, smth like:

has_logidze aliases: {old_title_column_name: :new_title_column_name}

(Using "alias" to match the exiting alias_attribute API)

ScotterC commented 5 months ago

Configuration is an interesting approach. However, column names could change many times so a key pair feels insufficient to fully deliver on that approach.

I don't think migrating the data oneself is a big deal but a readme section showcasing it. A section like "how Logidze handles table changes". This could also help clarify what kinds of logidze triggers accommodate new column changes and which ones don't. e.g. all columns excluding X seamlessly handles additional columns and renames but note the key change.

One bug to note, in the case where a Logidze user wanted the keys to be immutable, when you change column names but call it on old versions like

post.log_versions.each do |post|
  post.new_title
end

the versions with only values from post.old_title will return the latest version values for post.new_title.

palkan commented 5 months ago

A section like "how Logidze handles table changes"

Yeah, that's a great idea for the start.