<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Mutually Human Software - Blog</title>
  <id>tag:mutuallyhuman.com,2009:mephisto/blog</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://mutuallyhuman.com/feed/blog/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://mutuallyhuman.com/blog" rel="alternate" type="text/html"/>
  <updated>2009-01-06T02:34:31Z</updated>
  <entry xml:base="http://mutuallyhuman.com/">
    <author>
      <name>zdennis</name>
    </author>
    <id>tag:mutuallyhuman.com,2009-01-06:37</id>
    <published>2009-01-06T02:20:00Z</published>
    <updated>2009-01-06T02:34:31Z</updated>
    <category term="Blog"/>
    <link href="http://mutuallyhuman.com/2009/1/6/using-custom-activerecord-events-callbacks" rel="alternate" type="text/html"/>
    <title>Using custom ActiveRecord events/callbacks</title>
<summary type="html">&lt;p&gt;Sometimes you are presented with a situation where you should use custom callbacks/events in your ActiveRecord model.&lt;/p&gt;


	&lt;p&gt;For example, consider the case where you need to ship the line items of an Order after it has been paid. Do you put the logic
for creating a shipment in a controller, a model, or in an observer? If you use an observer, should you rely on the standard ActiveRecord
callbacks like &lt;em&gt;after_save&lt;/em&gt;?&lt;/p&gt;


	&lt;p&gt;Let&#8217;s take a brief walk through each possibility in a progression that takes us from what may
seem like the easiest solution to implement to what gives us the simplest, most maintainable code.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Sometimes you are presented with a situation where you should use custom callbacks/events in your ActiveRecord model.&lt;/p&gt;


	&lt;p&gt;For example, consider the case where you need to ship the line items of an Order after it has been paid. Do you put the logic
for creating a shipment in a controller, a model, or in an observer? If you use an observer, should you rely on the standard ActiveRecord
callbacks like &lt;em&gt;after_save&lt;/em&gt;?&lt;/p&gt;


	&lt;p&gt;Let&#8217;s take a brief walk through each possibility in a progression that takes us from what may
seem like the easiest solution to implement to what gives us the simplest, most maintainable code.&lt;/p&gt;
&lt;p&gt;Using a controller to house this kind of logic violates &lt;span class=&quot;caps&quot;&gt;SRP&lt;/span&gt; and leads to unnecessarily complex
controller actions. As an added penalty it makes writing controller examples much more painful as
there are more code execution paths. 
&lt;em&gt;I don&#8217;t think you should put your controller in the position of needing examples, but that&#8217;s for another post.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;This can lead to nasty looking actions:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;OrderPaymentsController&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    order = &lt;span class=&quot;co&quot;&gt;Order&lt;/span&gt;.find params[&lt;span class=&quot;sy&quot;&gt;:id&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; order.make_payment(params[&lt;span class=&quot;sy&quot;&gt;:amount&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; order.paid_in_full?&lt;tt&gt;
&lt;/tt&gt;        shipment = &lt;span class=&quot;co&quot;&gt;OrderShipment&lt;/span&gt;.new &lt;span class=&quot;sy&quot;&gt;:order&lt;/span&gt; =&amp;gt; order&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; shipment.save&lt;tt&gt;
&lt;/tt&gt;          ...&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;          ...&lt;tt&gt;
&lt;/tt&gt;        &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        ...&lt;tt&gt;
&lt;/tt&gt;      &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;There&#8217;s got to be a better approach. Let&#8217;s consider pushing this down into the Order model. This
moves us in the spirit of &lt;a href=&quot;http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model&quot;&gt;skinny controller, fat model&lt;/a&gt; . 
After all an order knows when it has been paid:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Order&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class=&quot;sy&quot;&gt;:payments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  after_save &lt;span class=&quot;sy&quot;&gt;:check_order_for_shipment&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;make_payment&lt;/span&gt;(amount)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;c&quot;&gt;# ... &lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  private&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;check_order_for_shipment&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; paid_in_full?&lt;tt&gt;
&lt;/tt&gt;      shipment = &lt;span class=&quot;co&quot;&gt;OrderShipment&lt;/span&gt;.create! &lt;span class=&quot;sy&quot;&gt;:order&lt;/span&gt; =&amp;gt; order&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;While this has the benefit of keeping the controller simple it really only moves the problem. Now our
model becomes more complex. It violates &lt;span class=&quot;caps&quot;&gt;SRP&lt;/span&gt; by including functionality that it shouldn&#8217;t be responsible for.
Why should an order know when and how to create a shipment? Practically speaking 
this will make writing and maintaining the Order model and its examples more difficult.&lt;/p&gt;


	&lt;p&gt;I&#8217;d rather extract the behaviour out into an observer that can be responsible for listening to an
event and then kicking off the action of creating the shipment. Doing this won&#8217;t add
unnecessary complexity to the Order model. Let&#8217;s extract it out in an OrderObserver:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;OrderObserver&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Observer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  observe &lt;span class=&quot;co&quot;&gt;Order&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;after_save&lt;/span&gt;(order)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; paid_in_full?&lt;tt&gt;
&lt;/tt&gt;      shipment = &lt;span class=&quot;co&quot;&gt;OrderShipment&lt;/span&gt;.create! &lt;span class=&quot;sy&quot;&gt;:order&lt;/span&gt; =&amp;gt; order&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This isolates the responsibility in the OrderObserver. It also lets us write
examples for this behaviour in isolation (Pat Maddox&#8217;s &lt;a href=&quot;http://github.com/pat-maddox/no-peeping-toms&quot;&gt;no-peeping-toms&lt;/a&gt; 
plugin is a great tool for isolating observer examples from model examples).&lt;/p&gt;


	&lt;p&gt;It&#8217;s reasonable to stop here and be satisfied, but the solution can still be improved with minimal effort.
Rather than relying on the &lt;em&gt;after_save&lt;/em&gt;
callback in the OrderObserver it would be clearer to introduce a &lt;em&gt;paid_in_full&lt;/em&gt; callback. This
removes an unnecessary conditional as well as explicitly expresses the intent of the callback.
This requires that we update both the OrderObserver and the Order model.&lt;/p&gt;


	&lt;p&gt;ActiveRecord already includes all of the necessary wiring to trigger events so we just need to update the
Order model to fire the &lt;em&gt;paid_in_full&lt;/em&gt; event at the right time:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Order&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class=&quot;sy&quot;&gt;:payments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;make_payment&lt;/span&gt;(amount)&lt;tt&gt;
&lt;/tt&gt;    payments.create &lt;span class=&quot;sy&quot;&gt;:amount&lt;/span&gt; =&amp;gt; amount&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; paid_in_full?&lt;tt&gt;
&lt;/tt&gt;      notify &lt;span class=&quot;sy&quot;&gt;:paid_in_full&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;The OrderObserver only needs to be updated to have a callback for the &lt;em&gt;paid_in_full&lt;/em&gt; event:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;OrderObserver&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Observer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  observe &lt;span class=&quot;co&quot;&gt;Order&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;paid_in_full&lt;/span&gt;(order)&lt;tt&gt;
&lt;/tt&gt;    shipment = &lt;span class=&quot;co&quot;&gt;OrderShipment&lt;/span&gt;.create! &lt;span class=&quot;sy&quot;&gt;:order&lt;/span&gt; =&amp;gt; order&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Now when a payment is made an event will be fired and the OrderObserver will listen for it and
start the process of creating an order shipment. This gives the code clean separation,
meaningful names, and an ability to easily open and extend the system later should more functionality
need to be added when an order is paid in full.&lt;/p&gt;


	&lt;p&gt;While it&#8217;s not always necessary to create custom callbacks and events there are times when it adds
value to the code by keeping the code clean, maintainable, and extendable. 
This is a technique I&#8217;ve been using for long time and I hope you might benefit from it as well.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://mutuallyhuman.com/">
    <author>
      <name>cdemyanovich</name>
    </author>
    <id>tag:mutuallyhuman.com,2008-12-19:34</id>
    <published>2008-12-19T17:02:00Z</published>
    <updated>2008-12-22T21:05:55Z</updated>
    <category term="Blog"/>
    <link href="http://mutuallyhuman.com/2008/12/19/software-craftsmanship-summit" rel="alternate" type="text/html"/>
    <title>Software Craftsmanship Summit</title>
<summary type="html">&lt;p&gt;On Saturday, December 14th, Craig, John, Mark, Matt and Zach joined about 30 other people for a summit on software craftsmanship in Libertyville, IL, at the office of &lt;a href=&quot;http://8thlight.com&quot;&gt;8th Light&lt;/a&gt;.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;On Saturday, December 14th, Craig, John, Mark, Matt and Zach joined about 30 other people for a summit on software craftsmanship in Libertyville, IL, at the office of &lt;a href=&quot;http://8thlight.com&quot;&gt;8th Light&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Working as several small groups, the participants charted their careers in software. While each person related his story, all others took note of similarities, differences or other interesting aspects of each person&#8217;s path. Meeting all together again, we reviewed what each group captured in the context of gathering raw material that we could distill into a definition of software craftsmanship. We then formed small groups different from the earlier ones to develop ways that we would identify a software craftsman. Finally, we gathered as one large group again to integrate all that we learned into a statement or even a manifesto of software craftsmanship.&lt;/p&gt;


	&lt;p&gt;Not uncommon for such a meeting, we generated at least as many questions as we did answers. This summit was only the beginning, though. Our &lt;a href=&quot;http://groups.google.com/group/software_craftsmanship&quot;&gt;community&lt;/a&gt; continued the &lt;a href=&quot;http://groups.google.com/group/software_craftsmanship/topics&quot;&gt;discussions&lt;/a&gt; and &lt;a href=&quot;http://groups.google.com/group/software_craftsmanship/web&quot;&gt;work&lt;/a&gt; mere hours after the summit was over.&lt;/p&gt;


	&lt;p&gt;Thank you to &lt;a href=&quot;http://8thlight.com&quot;&gt;8th Light&lt;/a&gt; for organizing and hosting the summit, and thank you to all those who attended. It was great to meet some of you for the first time, to see others again and to advance together our craft.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://mutuallyhuman.com/">
    <author>
      <name>cdemyanovich</name>
    </author>
    <id>tag:mutuallyhuman.com,2008-11-17:35</id>
    <published>2008-11-17T17:00:00Z</published>
    <updated>2008-12-22T21:06:09Z</updated>
    <category term="Blog"/>
    <link href="http://mutuallyhuman.com/2008/11/17/mhs-welcomes-matt-blodgett" rel="alternate" type="text/html"/>
    <title>&gt;&gt; MHS.welcome(Matt).on("17 Nov 2008")</title>
<summary type="html">&lt;p&gt;We&#8217;ve been working so much on great apps for our customers that we almost forgot to announce our newest human!&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;We&#8217;ve been working so much on great apps for our customers that we almost forgot to announce our newest human!&lt;/p&gt;
&lt;p&gt;The population of &lt;span class=&quot;caps&quot;&gt;MHS&lt;/span&gt; grew by one on November 17th when Matt Blodgett joined us. He brings a wealth of web development experience using &lt;span class=&quot;caps&quot;&gt;ASP&lt;/span&gt;.NET and SharePoint as primary tools. What&#8217;s more, Matt has a passion for creating great software and a desire to learn. He&#8217;s been demonstrating these characteristics since day one, contributing to projects and adding Mac &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt;, Ruby, Rails, Git, et. al. to his suite of tools.&lt;/p&gt;


	&lt;p&gt;Check out his &lt;a href=&quot;http://www.mattblodgett.com/&quot;&gt;blog&lt;/a&gt; or follow him as &lt;a href=&quot;http://twitter.com/mattblodgett&quot;&gt;@mattblodgett&lt;/a&gt; on Twitter.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://mutuallyhuman.com/">
    <author>
      <name>jhwang</name>
    </author>
    <id>tag:mutuallyhuman.com,2008-05-08:32</id>
    <published>2008-05-08T22:09:00Z</published>
    <updated>2008-12-22T21:06:00Z</updated>
    <category term="Blog"/>
    <link href="http://mutuallyhuman.com/2008/5/8/zach-dennis-to-teach-tutorial-at-railsconf" rel="alternate" type="text/html"/>
    <title>Zach Dennis to Teach Tutorial at RailsConf</title>
<summary type="html">&lt;p&gt;Zach Dennis will be leading a tutorial at &lt;a href=&quot;http://railsconf.com&quot;&gt;RailsConf 2008&lt;/a&gt;.  The topic he will be presenting on &lt;a href=&quot;http://en.oreilly.com/rails2008/public/schedule/detail/1962&quot;&gt;Refactoring Your Rails Application&lt;/a&gt;.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Zach Dennis will be leading a tutorial at &lt;a href=&quot;http://railsconf.com&quot;&gt;RailsConf 2008&lt;/a&gt;.  The topic he will be presenting on &lt;a href=&quot;http://en.oreilly.com/rails2008/public/schedule/detail/1962&quot;&gt;Refactoring Your Rails Application&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Tutorial Details&lt;/h4&gt;


	&lt;p&gt;&lt;strong&gt;Time:&lt;/strong&gt; 8:30am &#8211; 12:00pm Thursday, 05/29/2008&lt;br /&gt;
&lt;strong&gt;Location:&lt;/strong&gt; Portland Ballroom 251&lt;/p&gt;


	&lt;h4&gt;Summary&lt;/h4&gt;


	&lt;p&gt;Refactoring is an essential part of a developer’s life. It can be difficult to know when or what to refactor in a Rails application. Some common and more noticeable signs that you need to refactor are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;controllers becomes bloated&lt;/li&gt;
		&lt;li&gt;models become bloated&lt;/li&gt;
		&lt;li&gt;the view ends up embedding logic within its template&lt;/li&gt;
		&lt;li&gt;view helpers become large and complex, both in size and in number of methods&lt;/li&gt;
		&lt;li&gt;view partials rely on instance variables and constants rather then local variables&lt;/li&gt;
		&lt;li&gt;models start doing work for the view&lt;/li&gt;
		&lt;li&gt;tests become large, complex and painful to maintain&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Refactoring should be a continual process throughout the life of an application. In order to refactor well it requires the developer to have proper techniques, tools and discipline. For example:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;applying the single responsibility principle&lt;/li&gt;
		&lt;li&gt;extracting objects from bloated methods&lt;/li&gt;
		&lt;li&gt;splitting objects into two&lt;/li&gt;
		&lt;li&gt;identifying what goes in a model and what doesn’t&lt;/li&gt;
		&lt;li&gt;identifying what goes in a controller and what doesn’t&lt;/li&gt;
		&lt;li&gt;extracting presenters&lt;/li&gt;
		&lt;li&gt;when to use classes and when to use modules&lt;/li&gt;
		&lt;li&gt;using integration tests to help you refactor&lt;/li&gt;
		&lt;li&gt;writing better tests&lt;/li&gt;
		&lt;li&gt;writing clear and meaningful code&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;In this talk we will show the audience how to use the above refactoring techniques and tools to keep their Rails project humming along through development. Not only will they be able to apply these techniques to existing code, but they will be able to use these techniques to write better code from this point forward.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://mutuallyhuman.com/">
    <author>
      <name>jhwang</name>
    </author>
    <id>tag:mutuallyhuman.com,2008-05-05:31</id>
    <published>2008-05-05T09:32:00Z</published>
    <updated>2008-05-09T22:49:26Z</updated>
    <category term="Blog"/>
    <link href="http://mutuallyhuman.com/2008/5/5/mutuallyhuman-com-redesign" rel="alternate" type="text/html"/>
    <title>MutuallyHuman.com Redesign</title>
<content type="html">
            &lt;p&gt;Finally!  We bit the bullet and actualy redesigned the website.  Since we started the company, we&#8217;ve been too busy to work on our own website.  I guess it&#8217;s a good problem when you don&#8217;t have time to work on your own website.&lt;/p&gt;


	&lt;p&gt;We&#8217;re running our site on mephisto and hosted at slicehost.&lt;/p&gt;
          </content>  </entry>
</feed>
