假设您有一个 User
类:
class User
attr_accessor :widgets
end
和一个小部件
:
class Widget
attr_accessor :owner
end
并且您将一些小部件分配给用户:
user = User.new
widget = Widget.new
widget.owner = user
widget2 = Widget.new
widget2.owner = user
user.widgets = [widget, widget2]
现在你有一个user
→widgets
→owner
的递归。 user.inspect
为每个小部件显示相同的 user
引用一次,从而使输出变得困惑:
user.widgets.first.owner.widgets.first.owner
=> #<User:0x00000001cac820 @widgets=[#<Widget:0x00000001ca45f8 @owner=#<User:0x00000001cac820 ...>>, #<Widget:0x00000001c87a20 @owner=#<User:0x00000001cac820 ...>>]>
如果我们将此数据结构简化为哈希,我们将拥有:
{ user:
{ widgets: [ { widget: ... },
{ widget: ... } ]
}
}
我们可以传递它而不是分配widget.owner
,并且引用父user
会很容易。
我想知道是否有一种方法可以通过子对象访问父对象,而无需将所有者分配给所有子对象,接口(interface)可以像这样工作:
user = User.new
widget = Widget.new
user.widgets = [widget]
widget.parent
# => #<User:... @widgets=[#<Widget:...>]>
最佳答案
您正在寻找的是一位定制作家。没有parent
方法或 Object
上的等效方法或BaseObject
类,因为实现它需要对象跟踪碰巧指向它的所有其他对象。不过,当您需要该功能时,自定义编写器可以使其简单且易于实现。
class Widget
attr_accessor :owner
end
class User
attr_reader :widgets
def widgets=(widgets)
@widgets = widgets
widgets.each do |widget|
widget.owner = self
end
end
end
user = User.new
widget = Widget.new
user.widgets = [widget]
widget.owner #=> #<User:... @widgets=[#<Widget:...>]>
请注意,此自定义编写器仅涵盖常规分配,例如 user.widgets = [widget]
。如果你想做类似 user.widgets << widget
的事情,新的小部件不会被分配所有者。如果您希望能够做到这一点,您必须 monkeypatch Array
like this (不推荐),否则您必须创建 WidgetCollection
可能继承自 Array
的类。这就是ActiveRecord::Associations做。说到这里,如果您碰巧使用 Rails,那么一定要考虑使用 ActiveRecord 来为您完成这一切。看起来您在问的是普通的旧 ruby ,所以我给您一个普通的 ruby 答案。
关于ruby - 从子对象引用父对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31150753/