Skip to content

Instantly share code, notes, and snippets.

@emirikol
Created July 9, 2012 14:43
Show Gist options
  • Save emirikol/3076935 to your computer and use it in GitHub Desktop.
Save emirikol/3076935 to your computer and use it in GitHub Desktop.
Association methods
#tl;dr - user :extend, embrace module explosion.
#delegates are a classic and simple tool here, they allow you to mass produce simple forwarding functions to be replaced as needed. this is exactly what LOD is all about.
# first of all, without knowing the code I'd reject the claim that knowing how to stop a subset of workers is the factory's concern rather than the Worker class (not instance). in which case - why pass a factory instance at all? the following will work.
class Factory
has_many :machines, :inverse_of=>:factory
delegate :stop, :start, :eat, :to=>machines, :prefix=>true
end
class Machine
belongs_to :factory, :inverse_of=>:machines
def self.stop
working.all.map(&:stop)
end
end
f = Factory.first
f.machines_stop #though I would really prefer if generated method would be #stop_machines
#and it even lets you use scopes nicely
#if this doesn't fit your needs then personally I'd use association extension modules, this way the code is exactly where it belongs. the association of machines to a factory.
class Factory
has_many :machines, :extend => MachinesManage
#IIRC association_proxy method is available to functions of this module and can be used to access factory
delegate :stop, :start, :eat, :to=>machines, :prefix=>true
end
#which gives you the module explosion which I find acceptable. having many modules with 3-5 public methods each seems like a reasonable system to me. (unless resources provide similar interfaces and you can reuse/compose modules for more than one association, generate a range of anonymous modules from a set of variables, or the like)
#the problem you get stuck with regardless of all that is a very wide interface for a Factory
#this is almost an inherent feature when strictly applying LOD, which can maybe be addressed by using some funky dispatcher method instead of delegation like Factory#manage(assoc_name, action, *args). or better yet - learn to live with it?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment