Skip to content

Instantly share code, notes, and snippets.

@detournemint
Created March 28, 2016 16:02
Show Gist options
  • Save detournemint/3909c8339529548b49d9 to your computer and use it in GitHub Desktop.
Save detournemint/3909c8339529548b49d9 to your computer and use it in GitHub Desktop.
Example of agnostic relationship
class Opportunity < ActiveRecord::Base
has_many :notes
end
class Note < ActiveRecord::Base
end
On the opportunity model I want a way when the Note updates (the updated_at column changes) that a column on the opportunity (note_last_updated or similar) updates. Notes are used all over my app so i wanted to avoid having a specific after_update callback on the note model.
@brandonweiss
Copy link

Ah, I understand. I think we often look for a magical way to do something when there's just an obvious, dead-simple way, that's almost always going to be better than a magical way, if it ever even existed.

Avoiding the after_update hook makes sense, because more likely than not, you don't always want it to fire. Let's say you wanted to create a note in a test—you probably don't care that it's updating something on opportunity.

So all you have to do is make a class that wraps up this logic.

class NoteAndOpportunityUpdate

  def self.run(note, attributes = {})
    note.update!(attributes)
    note.opportunity.update!(column: "foobar")
  end

end

The name of the class is awful (because I don't have full context), but this is basically it. When you need to update a note in a way that modifies that one column on opportunity, use this class. And if it only happens in one place, like say, a particular controller action—then you don't even need the class, just inline the logic in the action. Does that make sense? This is basically the command pattern. The mutations gem is an example of a command pattern library for Ruby, although I would only use it if you find yourself doing something similar in lots of places. Otherwise just make a few simple classes as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment