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

Updating versions when schema changes #402

Closed
siassaj opened this issue Jul 27, 2014 · 7 comments
Closed

Updating versions when schema changes #402

siassaj opened this issue Jul 27, 2014 · 7 comments

Comments

@siassaj
Copy link

siassaj commented Jul 27, 2014

When table names or attributes change we need to have a way to maintain coherence with version records. Not just item_type, but also the serialised attributes in the object attribute. Since it's a string it's non trivial and requires special SQL in many cases.

I've ended up doing it this way because I didn't want to write that SQL, we aren't sure what db we'll end up with in prod. It's far from ideal, this sort of code ought to be in a tool with paper_trail, specifically to facilitate migrations.

Is this in the works, or does someone need to get started on it?

namespace :db do
  namespace :data_migration do
    namespace "20140726211253_rename_refill_report_to_service_report" do

      task :set_model do
        class PaperTrail::Version < ActiveRecord::Base
        end
      end

      desc "Rename 'RefillReport' item_types to 'ServiceReport'. PaperTrail::Version records have a polymorphic item relation."

      task up: :set_model do
        PaperTrail::Version.where(item_type: "RefillReport").update_all(item_type: "ServiceReport")
        PaperTrail::Version.where("item_type = 'Refill' OR item_type = 'Count'").each do |v|
          if v.object.present?
            v.update_attributes(object: v.object.gsub(/refill_report_id:/, "service_report_id:"))
          end
        end
      end

      desc "Rename 'ServiceReport' item_types to 'RefillReport'. PaperTrail::Version records have a polymorphic item relation."

      task down: :set_model do
        PaperTrail::Version.where(item_type: "ServiceReport").update_all(item_type: "RefillReport")
        PaperTrail::Version.where("item_type = 'Refill' OR item_type = 'Count'").each do |v|
          if v.object.present?
            v.update_attributes(object: v.object.gsub(/service_report_id:/, "refill_report_id:"))
          end
        end
      end

    end
  end
end
@siassaj
Copy link
Author

siassaj commented Jul 29, 2014

A conversation has lead me to some... thoughts...

I have been using paper_trail strictly to document the changes to the meaningful domain data. I have not considered using it to also document the history of changes to my Logical Data Model.

It seems that these are two concerns, the semantic business data (which I've been trying my best to use paper_trail for only) and the Logical Data Model underlying that.

Not sure what the least insane way to think about this is. Should old versions reflect the nature of the data structure? To illustrate

Person.family_name is changed to Person.surname on 2000-01-01

So my Person models can't access family_name/surname history post 2000-01-01 or I have to write something to deal with that programmatically. Which I really, really do not want to do.

... I hope some one else reads this stuff and throws in their 0.02

@batter
Copy link
Collaborator

batter commented Jul 31, 2014

Version 3.0.3 contains the new where_object method, which is designed for querying the attributes inside of versions / accessing versions corresponding to particular object states. See the details about it on #377 / #380.

In terms of renaming of tables and attributes, there isn't something built around updating versions to contain updated attribute names. My first thought with regards to how to accomplish this is probably building a rake task / script to take care of that, which it looks like you've already started on.

In terms of your idea about whether old versions should reflect the nature of the data structure at the time, that is up to you I suppose. If you want my opinion, I guess without too much consideration I think that it probably makes sense to update attribute names in old versions when a small change like the renaming of an attribute name occurs (i.e. family_name to surname). When it's additions of columns or even entire table renames I'm not so sure what the best policy is. I guess it all depends on how you want to organize the data and how you want it to perform.

In other words, perhaps instead of renaming your table from RefillReport to ServiceReport you should keep your RefillReport table for legacy purposes when you need to go back and access that old data. Or maybe consider subclassing RefillReport under ServiceReport but keeping tables for all of the subclasses of the ServiceReport base class. (i.e. ServiceReport becomes an Abstract Class; see the README for more methodologies on how to handle things like this). In the end there are many ways you can handle it, but in development there isn't always a 'correct' way to do it, it comes down to a combination of personal preference and what sort of functionality the user base is looking to get out of the implementation.

@siassaj
Copy link
Author

siassaj commented Aug 6, 2014

I'll get started and show you the source when it starts to resemble something useful.

@jaredbeck jaredbeck changed the title Maintaining coherency with migrations is convoluted Updating versions when schema changes Nov 1, 2017
@jaredbeck
Copy link
Member

Closing after three years of inactivity.

@siassaj
Copy link
Author

siassaj commented Nov 2, 2017

yeah... i forgot about this, sorry

@jaredbeck
Copy link
Member

yeah... i forgot about this, sorry

No worries! I enjoyed reading your discussion with Ben. It sounds like a difficult problem to solve generally, but interesting to think about.

@robwise
Copy link

robwise commented Nov 29, 2018

Sorry to comment on an old issue, but I just had this one come up.

On it's own, this isn't a showstopper.

But, if I combine this scenario with the rails_admin integration, the whole rails_admin interface 500s if I ever change a model name because PaperTrail is referencing an uninitialized constant.

Maybe it doesn't require a code change, but some mention in a "Gotchas" section of the README?

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

4 participants