开发者

has_many association after_load type callback

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 bett开发者_JAVA技巧er way to approach this situation?


For anyone interested, in the end I delved into ActiveRecord and came up with the following:

 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜