gpt4 book ai didi

ruby-on-rails - 在 has_many :through relationship, 上覆盖 ActiveRecord << 运算符以接受连接模型的数据

转载 作者:数据小太阳 更新时间:2023-10-29 06:58:12 24 4
gpt4 key购买 nike

我有三个类:Person、Position 和 Directory。

  • A Person has_many :directories, :through => :position.
  • 目录有_many :people, :through => :position.
  • 个人和目录都有_many :positions。
  • 除了具有 id、person_id 和 directory_id 之外,Position 模型还有一个或多个附加字段(例如,title)。

我希望能够在每次将人员添加到 Directory.people 集合时向连接模型添加数据,例如标题字段。通常的 << 运算符不会削减它。我估计:

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 对象的人员集合中,但不允许我将数据分配给连接模型。因此,在对该站点进行了大量研究之后,我找到了另一种方法,可以将人员添加到人员集合中,并将数据添加到链接人员和目录的位置,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")

同样,这似乎是错误的,因为我希望能够强调 Person 和 Directory 之间的关系,我认为这就是使用 has_many :through 合适的原因。

我想做的是使用 << 运算符,并只传递附加数据,例如:

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 :through 声明中重载了 << 运算符,如下所示:

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

让它工作的优点是它在语法上工作得很好,并且允许我在将 Person 添加到 Directory 对象的 people 集合时将数据简明地分配给连接对象(一个位置)。

但我无法让它工作,因为我需要能够访问 Directory 对象,其中 << 运算符左侧的人员集合是一个属性,以便构建一个 Position 并将其保存到数据库。

那么,我的问题是:

  1. 有没有办法从对象的属性访问对象?
  2. 或者,是否有另一种方法重载 << 运算符,以便我可以轻松地将数据分配给连接模型,同时将一个对象添加到集合中?

非常感谢您的帮助和周到的回复。我已经为此苦苦思索了半天,但无济于事。

回答感谢回答这个问题的 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"}}

最佳答案

您可以在 block 内使用 proxy_association 助手来获取关联,并使用 proxy_association.owner 来获取目录对象本身。参见 here有关这方面的更多信息。

关于ruby-on-rails - 在 has_many :through relationship, 上覆盖 ActiveRecord << 运算符以接受连接模型的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12846881/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com