That's my feeling too. Basically here are the options I can think of:

1. create callbacks (or validators) before_save, before_update, etc in the model to hijack the save/update method. The problem with this approach is that some methods skip the callbacks (or validators). e.g. increment, update_column, update_all. Right now Spree is not using any of them to update the count_on_hand column (used in rspec tests though). But this is a time bomb if Spree starts using those methods in the future.

2. The most effective way should be creating DB triggers. But it seems to be against the Rails-y way and portability is an issue. I find a gem https://github.com/jenseng/hair_trigger that sounds good for this. It can create triggers for MySQL, PostgreSQL, and SQLite. But still I don't feel comfortable going this far.

3. Just keep it simple. Spree::Stock model provide two methods adjust_count_on_hand and set_count_on_hand to update the count_on_hand column. Controller is not using any native ActiveRecord record (e.g. decrement) to update it. Might just modify these two methods to check track_inventory flag before updating it. Both methods call a private setter to do the actual work. May just simply update the setter.

Options 1 and 3 have same potential issue down the road if Spree start using methods that are not covered. If we have to pick one between them I would pick option 3 just for simplicity. Option 2 is the most effective way. Not sure we want to go that far.