【发布时间】:2011-04-23 20:16:23
【问题描述】:
我想记录一组个人之间的交互,每个人都被建模为一条消息,发送者和接收者:
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”关联回调。有没有其他我可以使用的方法,或者有更好的方法来解决这种情况?
【问题讨论】:
-
你在用
MyMessage对象做什么?它就像一个留言板,人们可以在其中删除收件箱和发件箱中的内容? -
所描述的情况是我能想到的最简单的情况,可以解决问题。我实际上并没有尝试创建消息框。想想看,而不是观察人群并记下他们每次互相发送信息的时间。
MyMessage对象仅用于为创建Message对象提供不同的接口,但它知道它所属的对象之一。 -
什么时候需要从接收者的角度创建消息?消息在发送时创建。
-
假设您正在为一位高中老师创建一个应用程序,用于记录孩子们何时互相发送笔记。他们可能不知道便条的内容,但他们可能会看到 Bob 将便条传递给 Jane。其中一项规范可能是您使用语法
@bob.messages.new(:direction => 'to', :correspondent => @jane)添加它。
标签: ruby-on-rails ruby-on-rails-3 activerecord associations