More Land Brokr/NCRE integration means more xml_response_fromhackery. This one involves the message center.
NCRE messages are STI trees. That is:
class Message < ActiveRecord::Base
acts_as_tree :order => 'created_at DESC'
end
class PurchaseMessage < Message
def summary
"blah blah"
end
end
class OpenHouseMessage < Message
def summary
"blah blah"
end
end
So the code to send a message thread over XML is:
class MessagesController < ActionController::Base
def show_thread
@thread = Message.find(params[:id]).root
respond_to do |wants|
wants.html
wants.xml { render :xml => @thread.to_xml(:include => [:children]) }
end
end
end
Which sends, for example, this XML:
<?xml version="1.0" encoding="UTF-8"?>
<purchase-message>
<children>
<child>
<replied-to></replied-to>
<body></body>
<folder>messages</folder>
<type>PurchaseMessage</type>
<read type="datetime">2006-06-01T15:47:35-04:00</read>
<subject></subject>
<recipient-id type="integer">1</recipient-id>
<id type="integer">108</id>
<sender-id type="integer">6</sender-id>
<parent-id type="integer">107</parent-id>
<created-at type="datetime">2006-06-01T15:46:44-04:00</created-at>
</child>
</children>
<replied-to type="datetime">2006-06-01T15:46:47-04:00</replied-to>
<body></body>
<folder>messages</folder>
<type>PurchaseMessage</type>
<read type="datetime">2006-06-01T15:45:45-04:00</read>
<subject></subject>
<recipient-id type="integer">6</recipient-id>
<id type="integer">107</id>
<sender-id type="integer">1</sender-id>
<parent-id></parent-id>
<created-at type="datetime">2006-06-01T15:45:08-04:00</created-at>
</purchase-message>
The ‘children’ and ‘child’ elements are the interesting part. Okay, cool, so it sent the whole thread, including any children. But now on Land Brokr I need to turn the children into the correct object, based on their type.
Here’s what I ended up writing on the Land Brokr side:
class MessageFactory
def self.new(h)
if h[:type]
h[:type].constantize.new(h)
else
Message.new(h)
end
end
end
class Message
attr :body, true
# and so on, for the other attributes
attr :children, true
def initialize(h)
@children = []
h.each { |k,v| send("#{k}=", v) }
end
def purchase_message=(m)
@children << m[0]
end
def open_house_message=(m)
@children << m[0]
end
def find(id)
xml_response_from("http://myncre.com/messages/show_thread/#{id}",
{ :child => MessageFactory })
end
end
Which means now I can do Message.find(165) and get back the whole thread.
One Comment
Yeah, thanks for removing my indentation, WordPress. Jerks.
Update: Yeah, it works now. Okay. Next time WordPress should stop being so dang “smart”.