I have a situation where i need to call something like this :
class Office
attr_accessor :workers, :id
def initialize
@workers = []
end
def workers worker
type = worker.type
resp = Worker.post("/office/#{@id}/workers.json", :worker => {:type => type})
worker = Worker.new()
resp.to_hash.each_pair do |k,v|
worker.send("#{k}=",v) if worker.respond_to?(k)
end
self.workers << worker
end
end
Worker class
class Worker
attr_accessor :office_id, :type, :id
def initialize(options={})
@office_id = options[:office].nil? ? nil : options[:office].id
@type = options[:type].nil? ? nil : options[:type].camelize
if !@office_id.nil?
resp = self.class.post("/office/#{@office_id}/workers.json", :worker => {:type => @type})
@id = resp.id
office = options[:office]
office.workers = self
end
end
def <<(worker)
if worker
type = worker.type
resp = Worker.post("/office/#{office_id}/workers.json", :worker => {:type => type})
debugger
@id = resp.id
resp.to_hash.each_pair do |k,v|
self.send("#{k}=",v) if self.respond_to?(k)
end
debugger
return self
end
end
I can do something like this very well
office = Office.new()
new_worker = Worker.new()
office.workers new_worker
But i need to do same what i have done above like the following. Before that, i need to change the initialize method of Office to fire up the def <<(worker)
method of the worker instance.
class Office
...
def initialize
@workers = Worker.new
@workers.office_id = self.id
end
office = Office.new()
new_worker = Worker.new()
office.workers << new_worker
Now the problem is, the later implementation creates 2 instances of the worker??
I'm not entirely sure, but I suppose you'd like to have this:
end
This way you can get rid of
Worker#<<
entirely and you should also remove the linein
Worker#initialize
sinceoffice.workers
is supposed to be an array. It's a bad idea to change the type of an attribute (duck-typing would be OK) back and forth because it's likely you lose track of the current state and you will run into errors sooner or later.To follow "Separation of Concerns", I would recommend to do the entire management of
workers
solely inOffice
, otherwise it gets too confusing too quickly and will be much harder to maintain on the long run.I'm not 100% certain why you aren't getting an error here, but since Office#workers last line is self.workers << worker, you are adding the new worker created in Office#workers (made on the 3rd line of the method), and then returning the workers object, which then gets #<< called again on it with the new worker created outside of the method