我有三类:个人,位置,和目录。
- 一个人的has_many:目录,:通过=>:位置。
- 一个目录的has_many:人:通过=>:位置。
- 两个人与目录的has_many:位置。
- 该位置模型中,除了具有一个ID,一个为person_id和directory_id,具有一个或多个附加字段(例如,标题)。
我希望能够做的就是将数据添加到加盟模式,比如标题场,每次我一个人添加到Directory.people收集时间。 通常<<操作将不会削减它。 ID EST:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
directory.people << person
这将一个人添加到一个目录对象的人收藏,但不会让我的数据分配给连接模型的机会。 所以,在这个网站做了很多的研究,我发现了另一种方式的个人数据添加到人收藏并添加链接人事和目录,ID EST的位置:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
position = person.positions.build(:directory_id => directory.id, :title => "Administrative Assistant")
position.save
这是麻烦的。 同样麻烦的方式是:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
position = Position.new(directory_id: directory.id, person_id: person.id, title: "Administrative Assistant")
再次,似乎是错误的,因为我希望能够强调人与目录之间的关系,我相信这是使用的has_many什么使:通过适当的。
我希望能够做的是使用<<操作,只是通过其它数据,例如:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
directory.people << person, :position => {:title => "Administrative Assistant"}
我已经重载<<在我的has_many操作:通过声明,如下所示:
has_many :people, :through => :positions do
def << *args
arg = args.first
if arg.is_a?(Person)
self.push([arg])
elsif arg.is_a?(Hash)
# Don't know what to do in here (see below)
else
raise "Invalid Value" # There's a better error to raise here, but good enough for now.
end
end
end
得到这个工作的好处是,它运作良好语法,并让我简明而添加的人到Directory对象的人收藏数据分配给参加对象(的位置)。
但我不能让它工作,因为我需要能够访问的目录对象,其中在<<运算符的左侧的人收藏是一个属性,以建立一个位置,并将其保存到数据库中。
所以,我的问题是:
- 有没有从一个对象的属性来访问对象的方法吗?
- 在备选方案中,有另一种方式重载<<操作,这样我可以很容易地将数据分配到加盟模式,同时加入一个对象的集合?
非常感谢您的帮助和深思熟虑的回应。 我已经远离黑客在这半天不得要领。
答感谢PinnyM,谁回答了这个问题,我能想出这个实现:
module AddToPeopleAndPositionExtension
def << *args
arg = args.first
if arg.is_a?(Person)
self.push([arg])
return self
elsif arg.is_a?(Hash)
directory = proxy_association.owner
person = arg[:person]
position = person.positions.build(:directory_id => directory.id, :title => arg[:position][:title])
position.save
else
raise "Invalid Value"
end
end
end
class Directory < ActiveRecord::Base
# Relationships
has_many :positions
has_many :people, :through => :positions, :extend => AddToPeopleAndPositionExtension
end
这让我叫<<运营商在标准的方式,如果我没在意就加入模型,如发生了什么:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
directory.people << person
而且,我还可以把它在指定的连接模式一样的属性的方法:
directory = Directory.last # Let's assume that retrieves a Directory object
person = Person.last # Let's assume that retrieves a Person object
directory.people << {:person => person, :position => {:title => "Administrative Assistant"}}