has_many 关联 after_load 类型回调
我想记录一组个体之间的交互,每个个体被建模为与发送者和接收者的消息:
class Message < ActiveRecord::Base
belongs_to :receiver, :class_name => 'Individual', :foreign_key => 'receiver_id'
belongs_to :sender, :class_name => 'Individual', :foreign_key => 'sender_id'
end
我想添加一个接口,通过该接口我可以记录从个体的角度发送的消息:
@bob.messages.new(:direction => 'to', :correspondent => @jane)
理想情况下,这会表现出来与 active_record has_many 关联完全相同。我决定对消息模型进行子类化,旨在创建可以以这种方式响应的东西 - 仅仅将方法添加到 Message 类似乎并不合适,因为对象需要对其“主要个体”有一些了解(在上面的情况下 @bob) 以便知道要创建哪个消息。
class Individual < AcitveRecord::Base
has_many :received_messages, :class_name => 'Message', :foreign_key => 'receiver_id'
has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id'
has_many :messages, :class_name => 'MyMessage',
:finder_sql =>'SELECT * FROM messages WHERE receiver_id = #{id} OR sender_id = #{id}',
:after_add => :set_user
def set_user(my_message)
my_message.principal_user = self
end
class MyMessage < Message
attr_accessor :principal_user
def correspondent
@principal_user == receiver ? sender : receiver
end
def direction
@principal_user == receiver ? "to" : "from"
end
... other methods ...
end
end
这几乎达到了我想要的效果。不幸的是,after_add 回调仅在将新对象添加到消息集合中时触发,而不是在每个对象首次加载到关联中时触发。
据我发现不存在“after_load”关联回调。我还可以使用其他方法,或者有更好的方法来处理这种情况吗?
I want to record interactions between a group of individuals each modelled as a message with a sender and a receiver:
class Message < ActiveRecord::Base
belongs_to :receiver, :class_name => 'Individual', :foreign_key => 'receiver_id'
belongs_to :sender, :class_name => 'Individual', :foreign_key => 'sender_id'
end
I would like to add an interface whereby I can record a message being sent from the point of view of an individual:
@bob.messages.new(:direction => 'to', :correspondent => @jane)
Ideally this would behave exactly like an active_record has_many association. I decided to subclass the message model, aiming to create something that could respond in this way - it didn't seem appropriate to just add the methods to the Message class, as the object needs to have some knowledge of its 'principal individual' (in the case above @bob) in order to know which Message to create.
class Individual < AcitveRecord::Base
has_many :received_messages, :class_name => 'Message', :foreign_key => 'receiver_id'
has_many :sent_messages, :class_name => 'Message', :foreign_key => 'sender_id'
has_many :messages, :class_name => 'MyMessage',
:finder_sql =>'SELECT * FROM messages WHERE receiver_id = #{id} OR sender_id = #{id}',
:after_add => :set_user
def set_user(my_message)
my_message.principal_user = self
end
class MyMessage < Message
attr_accessor :principal_user
def correspondent
@principal_user == receiver ? sender : receiver
end
def direction
@principal_user == receiver ? "to" : "from"
end
... other methods ...
end
end
This does almost what I want. Unfortunately the after_add callback fires only when new objects are added to the messages collection, not when each object is loaded into the association for the first time.
As far as I've found no 'after_load' association callback exists. Is there something else I can use, or a better way to approach this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于任何感兴趣的人,最后我深入研究了 ActiveRecord 并得出以下结论:
For anyone interested, in the end I delved into ActiveRecord and came up with the following: