如何在Ruby中关联来自不同类的实例

时间:2012-03-02 05:44:52

标签: ruby-on-rails ruby associations instance

我希望能够初始化一个新的Car对象并在参数中传递一个Person对象,这样它就可以保存在Person的@cars数组中。目前,我采用这种方法:

person = Person.new("Michael")
car = Car.new("Honda", "Accord")
person.add_car(car)
person.add_car(Car.new("Ford", "Taurus"))
person.add_car(Car.new("Toyota", "Prius"))
person.display

但是,我希望能够创建一个新的汽车实例并将其传递给我想要它的Person对象。例如:

person = Person.new("Michael")
Car.new("Honda", "Accord", person)
Car.new("Toyota", "Camry", person)
Car.new("Chevy", "Tahoe", person)
person.display

这甚至可能吗?

class Person

  attr_accessor :name

  def initialize(name)
    super
    @name = name
    @cars = []
  end

  def display
    puts "#{@name} has #{@cars.length} cars"
    puts "----------------------------"
    @cars.each do |car|
      puts "#{car.make} #{car.model}"
    end
  end

  def add_car(car)
    @cars.push(car)
  end

end 

class Car

  attr_accessor :make, :model

  def initialize(make, model)
    @model = model
    @make = make
  end

  def display
    puts "#{@make} #{@model}"
  end

end

3 个答案:

答案 0 :(得分:2)

是的,这是可能的,Car#initialize可以在其参数上调用方法:

class Car
  def initialize(make, model, person = nil)
    @model = model
    @make  = make
    person.add_car(self) if(person)
  end
  #...
end

答案 1 :(得分:1)

这将是我的实施:

class Car 
  attr_accessor :make, :model

  def initialize(make, model)
    self.make = make
    self.model= model
  end
end

人员类

class Person
  attr_accessor :name, :cars

  def initialize(name, cars=[])
    self.name = name
    self.cars = cars || []
  end

  def add_car(*args)
    raise ArgumentError, 'invalid arguments'  if (
        (args.size > 2 or args.size == 0) or 
        (args.size == 1 and !args[0].is_a?(Car))
      )
    new_car = (args.size == 2) ? Car.new(*args) : args[0]
    self.cars << new_car
    new_car
  end

end

现在你可以:

person = Person.new("Michael")
car = Car.new("Honda", "Accord")
person.add_car(car)
person.add_car("Ford", "Taurus")
person.add_car("Toyota", "Prius")
person.display

当make和model作为参数传递时,add_car方法会创建一个新车。

答案 2 :(得分:0)

是的,有可能在mu is too short的答案得到证实,但这在我看来并不合理。如果没有Person,您的汽车就无法在任何环境中使用,并且所述参数不会构建构建Car对象所需的任何数据。

我会设计如下API:

class Person
  def initialize(name)
    @name = name
  end

  def cars
    @cars ||= Array.new  # Equivalent to @cars || @cars = []
  end
end

person = Person.new 'Michael'

taurus = Car.new 'Ford', 'Taurus'
prius = Car.new 'Toyota', 'Prius'

person.cars << taurus << prius << Car.new('Honda', 'Accord')

这是一种更简单,更直接的KandadaBoggu实施形式,它利用Array#<<方法自然地将CarPerson相关联,并且还兼作属性读者。