opensource-ios opensource-ios - 5 months ago 9
Ruby Question

How to access all created objects and update attributes

I have a employee class where i stores employee details like age, DOB and Points earned.

class Employee
attr_accessor :id, :dob, :points

def initialize
@id = id
@dob = dob
@points = points
end

def tranfer_points
# Access both employee objects and add points to one and remove points from other
end

end


emp_one = Employee.new(1,"2 Jan 1990",400)
emp_two = Employee.new(2,"12 Jan 1986",700)

emp_two.transfer()


I want to know what is the best practice to maintain all created objects, so that i can transfer points from one employee to other.

Should i use class variable here, would that be a good solution, is it a standard practice?

like below

class Employee
@@all_employee = Hash.new
attr_accessor :id, :dob, :points

def initialize
@id = id
@dob = dob
@points = points
add_all_employee
end

def add_all_employee
@@all_employee[id] = self
end

def tranfer_points(i,points)
b = @@all_employee[i]
self.balance -= points
b.points += points
end

end


Any help here would be appreciated. Thanks.

Answer

Here is an example of how you can do this.

With database:

class Employee
  def tranfer_points_to(recipient, num_points)
    Employee.transaction do
      self.update!(points: self.points - num_points)
      recipient.update!(points: recipient.points + num_points)
    end
  end
end

Using Rails Transaction would be a good way to ensure you don't accidentally update one and not the other, in case there is an exception raised inside this block.

Without database:

class Employee
  def tranfer_points_to(recipient, num_points)
    self.points -= num_points
    recipient.points += num_points
  end
end

UPDATE: To answer your comments:

If you consider using db, then it's a no brainer, just save the model. Without the db, it's common to use some parent class to "hold" employee instances. An example:

class Company
  attr_reader :employees

  def initialize
    @employees = []
  end

  def add_employee(id, dob, points)
    employees.push(Employee.new(id, dob, points))
  end

  def tranfer_points(from_employee_id, to_employee_id, num_points)
    find_employee_by_id(from_employee_id).points -= num_points
    find_employee_by_id(to_employee_id).points += num_points
  end

  def find_employee_by_id(id)
    employees.find { |e| e.id == id }
  end
end

company = Company.new
company.add_employee(1, "2 Jan 1990", 400)
company.add_employee(2, "2 Jan 1991", 400)
company.transfer_points(1, 2, 200)

company.find_employee_by_id(1).points => 200
company.find_employee_by_id(2).points => 600