So I’ve been wrestling through another technical problem the last couple hours. I have databased email formats that are structured as rhtml so that they are both dynamic and easy to modify. Nothing new here. I want to be able to pre-render them using render_to_string(:inline=>code) so that I can capture the output and store that to database as a log of which messages are sent to whom.
The problem lies in my desire to do this at both the model and controller level. The function render_to_string is available strictly within the scope of the controller. There is probably a simple reference or something that can be used to drop the functionality to the model level, but after scraping around the internet for half an hour the best I could come up with is some obscure reference to using blocks…
I’ve spent almost a full year avoiding learning more about blocks. I’ve written thousands of lines of ruby code and have failed to really come to understand one of the most fundamental advantages this language has to offer. In this case using blocks allows me to yield from the model to the controller, execute render_to_string in the controller scope and pass the result back into the model. On a pragmatic level this is really cool because while it is very common to have a parent object have access to all aspects of its member objects it is not common to be able to allow those members access to their parent, but the magic of blocks goes much deeper.
I need to spend a little more time looking at ruby from an academic perspective so I can work more effectively.
code sample:
Controller level
def refer_to_provider
@order = Order.find(params[:id])
@shipment = @order.order_shipments.find(params[:shipment_id]) if @order
if @shipment
@shipment.refer{|opts| render_to_string(opts)}
flash[:notice]="Shipment has been referred"
redirect_to :action=>:show,:id=>@order.id
end
end
Model level
def refer
mark_referred
variables = {:order=>self.order, :shipment=>self}
format = CommunicationFormat.find_by_token("submit_to_provider")
subject = yield(:inline=>format.subject, :locals => variables)
body = yield(:inline=>format.subject, :locals => variables)
Sender.deliver_send("orders@yourdomain.com", self.provider.fullfillment_center_email.address, format.token, subject, body, self.order)
end

