我想记录一组个人之间的互动,每个人都建模为发送者和接收者的消息:
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'关联回调存在。还有其他我可以使用的东西,或者更好的方法来解决这种情况吗?
答案 0 :(得分:1)
对于任何有兴趣的人,最后我深入研究了ActiveRecord并提出了以下内容:
has_many :messages, :class_name => 'MyMessage',
:finder_sql =>'SELECT * FROM messages WHERE receiver_id = #{id} OR sender_id = #{id}',
:after_add => :set_user do
def find_target
messages = super
messages.each {|m| m.principal_user = proxy_owner}
messages
end
end