Skip to main content

Attaching a Characteristic To Multiple Models

Rails • Asked by Chris Zempel

I've got these models:

class Firm
  has_many :funds
end

class Fund
  belongs_to :firm
  has_many :investments
end

class Investment
  belongs_to :fund
  has_many :investments
end

class Company
  belongs_to :investment
end

With each one of these models, I'm directly concerned with the identity and thread of continuity each one has over time, and not necessarily what information there actually is about it (I don't care what info exists about a company at a given time, just that the info for a company actually belongs to that company).

Now each of these models need to have a cashflow attached to them. This object doesn't really have a conceptual identity, it just describes a particular characteristic of the model it's attached to (info about money in, money out, and when it occurs). Right now, I see a couple ways forward:

1) Make a single cashflow class that I can attach agnostically to any aforementioned model. The gist of the implementation looking like this:

class Cashflow
  #has attached_id, attached_type
  def belongs_to
    "#{attached_type.capitalize.constantize}".find(attached_id)
  end
end

#Then I can also write some cashflow-related methods that I attach to the models through a concern or something like this: 

class Company
  def cashflows
    Cashflow.where(belongs_to: self)
  end
end

2) Make individual cashflow classes for every model

class CompanyCashflow
  #does cashflow stuff
end

#FirmCashflow, FundCashflow, etc...

3) Or a more polymorphic approach: have a base cashflow class that I instantiate in a scoped way, so I can isolate model-specific logic (which I'm not sure if I'll need yet) there:

class Cashflow < ActiveRecord::Base
  #cashflow stuff

  def initialize(model)
    attached_type = model.class
    attached_id = model.id
end

class CompanyCashflow < Cashflow
  #company specific stuff
  def initialize(model)
    #does company-specific stuff
    super
  end
end

@cashflow = Cashflow.new(@company)

The main axis I want to think upon here is, eventual efficiency. If I have to go in and change this down the line after I have production data, that's not very efficient. First, how would you attach a cashflow to these other models? But second, and more importantly, what sort of reasoning, tradeoffs, and experiences inform your choice of designing the domain this way (or most pertinently, what's the very first thing you think before diving down into an intuitive reaction?)


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 27,623+ developers who get early access to new screencasts, articles, guides, updates, and more.

    By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

    More of a social being? We're also on Twitter and YouTube.