<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Rails Forum - Ruby on Rails Help and Discussion Forum - Refactoring on Rails: Move to Model]]></title>
		<link>http://railsforum.com/viewtopic.php?id=699</link>
		<description><![CDATA[The most recent posts in Refactoring on Rails: Move to Model.]]></description>
		<lastBuildDate>Wed, 06 May 2009 05:39:49 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96601#p96601</link>
			<description><![CDATA[<div class="quotebox"><cite>alexrothenberg wrote:</cite><blockquote><p>Several months ago I got curious about how it all worked and wrote up a post of my investigations which you may find useful <a href="http://www.alexrothenberg.com/2009/02/investigating-how-symbol-toproc-works.html">http://www.alexrothenberg.com/2009/02/i &#133; works.html</a> and of course Ryan Bates did a great Railscast of the same several months after he posted this article which you can watch at <a href="http://railscasts.com/episodes/6-shortcut-blocks-with-symbol-to-proc">http://railscasts.com/episodes/6-shortc &#133; ol-to-proc</a></p></blockquote></div><p>Thanks for the clarification, Alex. Much appreciated.</p>]]></description>
			<author><![CDATA[dummy@example.com (N0NS3QUiTUR)]]></author>
			<pubDate>Wed, 06 May 2009 05:39:49 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96601#p96601</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96513#p96513</link>
			<description><![CDATA[<div class="quotebox"><cite>lassebunk wrote:</cite><blockquote><p>Thanks for your replies - I&#039;ll look into it... And not use it after reading Johnson&#039;s reply ;-)</p></blockquote></div><p>I agree the symbol-to-proc syntax looks somewhat confusing but once you get used to it I find it a useful shorthand and would not avoid using it.&nbsp; In fact while it started as a Rails extension to the Ruby class Symbol it has moved into the Ruby core with 1.8.7 and 1.9 so I expect we&#039;ll all be seeing more of it.</p><p>Several months ago I got curious about how it all worked and wrote up a post of my investigations which you may find useful <a href="http://www.alexrothenberg.com/2009/02/investigating-how-symbol-toproc-works.html">http://www.alexrothenberg.com/2009/02/i &#133; works.html</a> and of course Ryan Bates did a great Railscast of the same several months after he posted this article which you can watch at <a href="http://railscasts.com/episodes/6-shortcut-blocks-with-symbol-to-proc">http://railscasts.com/episodes/6-shortc &#133; ol-to-proc</a></p>]]></description>
			<author><![CDATA[dummy@example.com (alexrothenberg)]]></author>
			<pubDate>Tue, 05 May 2009 17:55:22 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96513#p96513</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96446#p96446</link>
			<description><![CDATA[<div class="quotebox"><cite>Duplex wrote:</cite><blockquote><p><a href="http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand">http://blog.hasmanythrough.com/2006/3/7 &#133; -shorthand</a></p><p>google for &quot;rails symbol to proc&quot; for more blog posts etc. about this</p></blockquote></div><div class="quotebox"><cite>Johnson wrote:</cite><blockquote><p>Although it looks cool, it is not recommended to use that kind of shortcut.</p></blockquote></div><p>Thanks for your replies - I&#039;ll look into it... And not use it after reading Johnson&#039;s reply ;-)</p>]]></description>
			<author><![CDATA[dummy@example.com (lbunk)]]></author>
			<pubDate>Tue, 05 May 2009 07:57:59 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96446#p96446</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96338#p96338</link>
			<description><![CDATA[<p>Regarding the following:<br /><pre name="code" class="ruby:nogutter">sections.delete_if(&amp;:blank?)</pre><br />Although it looks cool, it is not recommended to use that kind of shortcut.</p>]]></description>
			<author><![CDATA[dummy@example.com (Johnson)]]></author>
			<pubDate>Mon, 04 May 2009 08:15:26 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96338#p96338</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96286#p96286</link>
			<description><![CDATA[<p><a href="http://blog.hasmanythrough.com/2006/3/7/symbol-to-proc-shorthand">http://blog.hasmanythrough.com/2006/3/7 &#133; -shorthand</a></p><p>google for &quot;rails symbol to proc&quot; for more blog posts etc. about this</p>]]></description>
			<author><![CDATA[dummy@example.com (Duplex)]]></author>
			<pubDate>Sun, 03 May 2009 19:36:51 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96286#p96286</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=96285#p96285</link>
			<description><![CDATA[<p>Thanks for this post - it&#039;s really helpful while learning ruby/rails.</p><p>Regarding the following:<br /><pre name="code" class="ruby:nogutter">sections.delete_if(&amp;:blank?)</pre><br />I understand what it does but haven&#039;t been able to find any information on the &amp;: part. Could you please explain what this means or send a link to a doc explaining it?</p>]]></description>
			<author><![CDATA[dummy@example.com (lbunk)]]></author>
			<pubDate>Sun, 03 May 2009 19:17:57 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=96285#p96285</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=6134#p6134</link>
			<description><![CDATA[<p>Thanks Ryan for the lovely code - you&#039;ve certainly made my full_address method a lot more elegant and useful. <img src="http://railsforum.com/img/smilies/cool.png" width="15" height="15" alt="cool" /></p><p>After I had posted I found some examples online of using application helpers and ended up writing pretty much what you wrote for showing &quot;Not supplied&quot; when something was blank. I&#039;ve not really used helpers a great deal yet but am starting to. I guess when things get repetative in the view and don&#039;t seem to fit in the model then helpers are a good solution.</p><p>Both my view and model are now looking a lot better. Thanks again for the great advice. BTW I think you should link to the other refactoring tutorials at the top of this one.</p>]]></description>
			<author><![CDATA[dummy@example.com (cathyb)]]></author>
			<pubDate>Thu, 16 Nov 2006 11:46:41 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=6134#p6134</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=6079#p6079</link>
			<description><![CDATA[<p>Very good questions Cathy!</p><p>The full_address method can be greatly simplified by using a technique similar to what I did in the article - which is placing the address sections in an array and joining that.</p><p><pre name="code" class="ruby:nogutter">def full_address(join_str = &#039;, &#039;)<br />&nbsp; sections = [address_line_1, address_line_2, address_line_3] # etc...<br />&nbsp; sections.delete_if(&amp;:blank?) # removes any blank entries from the array<br />&nbsp; sections.join(join_str)<br />end</pre><br />Notice I passed the join string as a parameter, this way you can change it when calling the method.</p><p>You can go one step further to clean this up a bit more:</p><p><pre name="code" class="ruby:nogutter">def full_address(join_str = &#039;, &#039;)<br />&nbsp; address_sections.delete_if(&amp;:blank?).join(join_str)<br />end</p><p>def address_sections<br />&nbsp; [address_line_1, address_line_2, address_line_3]<br />end</pre><br />As for your second question, I would hesitate to move this &quot;Not Supplied&quot; logic into the model. First of all you will need to handle this for many different attributes and models. Second, if you override the original attribute it will probably cause problems at the model/controller level. Lastly you may want to handle this differently in different views.</p><p>Certainly keeping this in the view isn&#039;t optimal either. What I would do is create a helper method that handles this for you. You can then input any value you want and it will return &quot;Not Supplied&quot; automatically when blank. For example:</p><p><pre name="code" class="ruby:nogutter"># in view<br />&lt;%= not_supplied_if_blank @person.job_title %&gt;</p><p># in application_helper<br />def not_supplied_if_blank(value)<br />&nbsp; value.blank? ? &quot;Not Supplied&quot; : value<br />end</pre><br />You may want to rename that method.</p>]]></description>
			<author><![CDATA[dummy@example.com (ryanb)]]></author>
			<pubDate>Wed, 15 Nov 2006 18:48:49 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=6079#p6079</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=6064#p6064</link>
			<description><![CDATA[<p>This refactoring is great and I&#039;m looking forward to the rest of this series of tutorials.</p><p>I&#039;ve done something similar in my person model to create a full_address method from all the individual address fields. I&#039;m sure this could be DRYied up somewhat.</p><p><pre name="code" class="ruby:nogutter">&nbsp; &nbsp; def full_address<br />&nbsp; &nbsp; &nbsp; &nbsp; result = &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; unless address_line_1.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += address_line_1<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless address_line_2.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += address_line_2<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + address_line_2<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless address_line_3.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += address_line_3<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + address_line_3<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless address_line_4.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += address_line_4<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + address_line_4<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless town.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += town<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + town<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless county.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += county<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + county<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; unless postcode.blank?<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if result == &#039;&#039;<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += postcode<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; result += &#039;, &#039; + postcode<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; end<br />&nbsp; &nbsp; &nbsp; &nbsp; result<br />&nbsp; &nbsp; end</pre><br />The above puts whatever parts of the address that exist all on one line with commas after each bit. However in a different view on my app I want to display the address differently with each part on a separate line with &lt;br&gt; in between instead of commas. Would I be best creating a new method full_address_multi_line or can I adapt my existing method to do both?</p><p>Also when I am displaying the person&#039;s profile details in the view, where a field is not completed I might want to display &quot;Not supplied&quot; or &quot;N/A&quot;. Is this best handled in the view or could it be moved to the model too? At the minute I&#039;ve got a lot of stuff like this in my view:</p><p><pre name="code" class="ruby:nogutter">&lt;%= if @person.job_title.blank? <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;Not supplied&quot; <br />&nbsp; &nbsp; &nbsp; &nbsp; else <br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @person.job_title <br />&nbsp; &nbsp; &nbsp; &nbsp; end %&gt;</pre></p>]]></description>
			<author><![CDATA[dummy@example.com (cathyb)]]></author>
			<pubDate>Wed, 15 Nov 2006 14:16:47 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=6064#p6064</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=6047#p6047</link>
			<description><![CDATA[<p>Excellent tutorial, thank you Ryan.&nbsp; I was starting to wonder what the Model&#039;s were for. <img src="http://railsforum.com/img/smilies/wink.png" width="15" height="15" alt="wink" /></p><p>I should really get a rails book...</p>]]></description>
			<author><![CDATA[dummy@example.com (jwcooper)]]></author>
			<pubDate>Wed, 15 Nov 2006 01:53:16 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=6047#p6047</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=3656#p3656</link>
			<description><![CDATA[<p>RAILSforum is turning out to be a great resource for Tutorials.<br />Nice work&nbsp; </p><p><a href="http://www.top-ten-tutorials.com/story/Refactoring-on-Rails-Move-to-Model">Added</a> this one as well to my growing (140+) collection below</p>]]></description>
			<author><![CDATA[dummy@example.com (boyles)]]></author>
			<pubDate>Mon, 25 Sep 2006 20:36:26 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=3656#p3656</guid>
		</item>
		<item>
			<title><![CDATA[Re: Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=3635#p3635</link>
			<description><![CDATA[<p>Nicely done! I wish I&#039;d seen this before I wrote my online billing system. I did end up doing this, but it was a lot more muddling through that I&#039;d have otherwise had. <img src="http://railsforum.com/img/smilies/wink.png" width="15" height="15" alt="wink" /></p>]]></description>
			<author><![CDATA[dummy@example.com (Kelli)]]></author>
			<pubDate>Mon, 25 Sep 2006 16:52:42 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=3635#p3635</guid>
		</item>
		<item>
			<title><![CDATA[Refactoring on Rails: Move to Model]]></title>
			<link>http://railsforum.com/viewtopic.php?pid=3617#p3617</link>
			<description><![CDATA[<p>This is the first article in a series which will cover various refactoring techniques that are specific to Rails. Refactoring is used to improve the design of existing code without changing its functionality.</p><p>The first refactoring I will be discussing involves taking a bit of logic out of the view and placing it in the model. This can clean up the views quite nicely.</p><p>Let&#039;s start out with a very simple example. We have a <strong>Person</strong> model with <strong>first_name</strong>, <strong>last_name</strong>, and <strong>middle_initial</strong> attributes. In our view we have this code:</p><p><pre name="code" class="ruby:nogutter">Full Name:<br />&lt;%= @person.first_name %&gt;<br />&lt;% unless @person.middle_initial.blank? %&gt;<br />&nbsp; &lt;%= @person.middle_initial %&gt;.<br />&lt;% end %&gt;<br />&lt;%= @person.last_name %&gt;</pre><br />Not very pretty. Even worse, this code is repeated several times throughout the application. To remove this duplication and to clean up the views, we can define a method in the Person class to handle this logic.</p><p><pre name="code" class="ruby:nogutter">class Person &lt; ActiveRecord::Base<br />&nbsp; def full_name<br />&nbsp; &nbsp; result = first_name + &#039; &#039;<br />&nbsp; &nbsp; unless middle_initial.blank?<br />&nbsp; &nbsp; &nbsp; result += middle_initial + &#039;. &#039;<br />&nbsp; &nbsp; end<br />&nbsp; &nbsp; result += last_name<br />&nbsp; &nbsp; result<br />&nbsp; end<br />end</pre><br />This makes the view much nicer:</p><p><pre name="code" class="ruby:nogutter">Full Name: &lt;%= person.full_name %&gt;</pre><br />We successfully shoved the logic into the Person model, but I&#039;m still not satisfied. I think we can clean up the full_name method, but before we do that, let&#039;s create some tests to make sure everything continues to work as we do the cleaning. Tests are very important when refactoring to make sure we don&#039;t break anything as we improve the code.</p><p><pre name="code" class="ruby:nogutter"># in person_test.rb<br />def setup<br />&nbsp; @person = Person.new(:first_name =&gt; &#039;John&#039;, :last_name =&gt; &#039;Smith&#039;)<br />end</p><p>def test_full_name<br />&nbsp; assert_equal &#039;John Smith&#039;, @person.full_name<br />end</p><p>def test_full_name_with_middle_initial<br />&nbsp; @person.middle_initial = &#039;A&#039;<br />&nbsp; assert_equal &#039;John A. Smith&#039;, @person.full_name<br />end</pre><br />Good, the tests are passing so now it&#039;s time to improve the full_name method. I would like to remove that temporary &quot;result&quot; variable and merge it all onto one line. I can use an array to help me out. Maybe something like this:</p><p><pre name="code" class="ruby:nogutter">def full_name<br />&nbsp; [first_name, middle_initial, last_name].join(&#039; &#039;)<br />end</pre><br />That looks nice and tidy, but unsurprisingly it fails both of the tests. It fails the second test because there&#039;s no period, so let&#039;s create a new method to return a middle initial with a period:</p><p><pre name="code" class="ruby:nogutter">def middle_initial_with_period<br />&nbsp; middle_initial + &#039;.&#039; unless middle_initial.blank?<br />end</p><p>def full_name<br />&nbsp; [first_name, middle_initial_with_period, last_name].join(&#039; &#039;)<br />end</pre><br />The second test is working now, but the first test still fails because there&#039;s an extra space in there when no middle initial is defined. We can remove that by using array&#039;s &quot;compact&quot; method like this:</p><p><pre name="code" class="ruby:nogutter">def full_name<br />&nbsp; [first_name, middle_initial_with_period, last_name].compact.join(&#039; &#039;)<br />end</pre><br />Our tests are all passing now. Yay!</p><p>Wait one minute, I hear someone say, the compact method just removes nil values, what if the middle initial is an empty string? Well let&#039;s add a test and find out:</p><p><pre name="code" class="ruby:nogutter">def test_full_name_with_empty_middle_initial<br />&nbsp; @person.middle_initial = &#039;&#039;<br />&nbsp; assert_equal &#039;John Smith&#039;, @person.full_name<br />end</pre><br />Surprisingly this passes successfully without us changing anything. Why? Because the middle_initial_with_period method already takes care of empty strings and will return nothing (nil) if middle_initial is blank.</p><p>In this tutorial you learned how to refactor code from the view into the model, but this can just as easily be applied to code in the controller or any other part of the application. Your job is to look through your current rails projects for code that can be moved into a model. Usually if it can be moved into a model, it should, but just be careful to keep view/controller specific code out of the model. For example, don&#039;t move HTML code into the model.</p><p>If you found this useful, keep an eye out for the next Refactoring on Rails article. In the meantime, check out Martin Fowler&#039;s <strong>excellent</strong> book: <a href="http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/">Refactoring</a>.</p><p>Check out the next article in this series: <a href="http://railsforum.com/viewtopic.php?id=737">Multiple Scopes in Controller</a></p>]]></description>
			<author><![CDATA[dummy@example.com (ryanb)]]></author>
			<pubDate>Sun, 24 Sep 2006 22:56:51 +0000</pubDate>
			<guid>http://railsforum.com/viewtopic.php?pid=3617#p3617</guid>
		</item>
	</channel>
</rss>
