<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Richard Hart / Hates_ &#187; rails</title>
	<atom:link href="http://www.ur-ban.com/blog/category/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ur-ban.com/blog</link>
	<description>Programming &#38; Life - ur-ban.com</description>
	<lastBuildDate>Sat, 18 Feb 2012 14:20:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Devise Omniauth Dynamic Providers</title>
		<link>http://www.ur-ban.com/blog/2011/04/30/devise-omniauth-dynamic-providers/</link>
		<comments>http://www.ur-ban.com/blog/2011/04/30/devise-omniauth-dynamic-providers/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 13:57:54 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=2097</guid>
		<description><![CDATA[My current project www.viewshound.com requires different users to have different scopes for their Facebook authentication. Warden supports dynamic providers out of the box. To get it working with Devise was pretty easy, just a couple of minor changes were needed especially to support Facebook. First up was creating the new route. As I&#8217;m using a [...]]]></description>
			<content:encoded><![CDATA[<p>My current project <a href="http://www.viewshound.com">www.viewshound.com</a> requires different users to have different scopes for their Facebook authentication. Warden supports <a href="https://github.com/intridea/omniauth/wiki/Dynamic-Providers">dynamic providers</a> out of the box. To get it working with Devise was pretty easy, just a couple of minor changes were needed especially to support Facebook.</p>
<p>First up was creating the new route. As I&#8217;m using a controller called Omniauth and not Session, the <strong>:to</strong> attribute is different. The other thing to note is I&#8217;m matching <strong>/users/auth/facebook/setup</strong>, not <strong>/auth/facebook/setup</strong> like in the Warden documentation.</p>
<p>routes.rb</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; devise_for <span style="color:#ff3333; font-weight:bold;">:users</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:controllers</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:omniauth_callbacks</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;omniauth&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>, <br />
&nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:skip</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:sessions</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; match <span style="color:#996600;">'/users/auth/facebook/setup'</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'omniauth#setup'</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
</pre>
<p>Next we create the new setup action for Warden to call. The docs use <strong>consumer_key</strong> and <strong>consumer_secret</strong>, but facebook expects <strong>client_id</strong> and <strong>client_secret</strong>, so be sure to use those instead. This is where I make changes to the scope based on the current user if they are signed in or not. So a user can re-authenticate with Facebook to get more permissions for their account if they wish.</p>
<p>omniauth_controller.rb</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color:#9966CC; font-weight:bold;">class</span> OmniauthController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Devise::OmniauthCallbacksController</span><br />
<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> setup<br />
&nbsp; &nbsp; &nbsp; request.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'omniauth.strategy'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">client_id</span> = <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span>your_facebook_id_here<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; request.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'omniauth.strategy'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">client_secret</span> = <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span>your_facebook_secret_here<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; request.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'omniauth.strategy'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">options</span> = <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">&#123;</span>:scope <span style="color:#006600; font-weight:bold;">=&gt;</span> your_facebook_scope_here<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; render <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Setup complete.&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">404</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
</pre>
<p>Finally change the devise.rb initializer to support the new setup.</p>
<p>devise.rb</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; config.<span style="color:#9900CC;">omniauth</span> <span style="color:#ff3333; font-weight:bold;">:facebook</span>, <span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#ff3333; font-weight:bold;">:setup</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span></div></div>
</pre>
<p>Restart your application and you should be good to go.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2011/04/30/devise-omniauth-dynamic-providers/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Paperclip S3 expiring_url with styles and SSL</title>
		<link>http://www.ur-ban.com/blog/2010/12/07/paperclip-s3-expiring_url-with-styles-and-ssl/</link>
		<comments>http://www.ur-ban.com/blog/2010/12/07/paperclip-s3-expiring_url-with-styles-and-ssl/#comments</comments>
		<pubDate>Tue, 07 Dec 2010 22:17:06 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[paperclip]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=1956</guid>
		<description><![CDATA[A current requirement is that assets uploaded to Amazon S3 must be accessed via SSL and use an expiring URL. Using an expiring url with Paperclip is extremely easy. &#160; my_model.image.expiring_url&#40;5&#41; The problem is expiring_url doesn&#8217;t let you choose a style and doesn&#8217;t use https, which breaks our SSL site. To add the behaviour was [...]]]></description>
			<content:encoded><![CDATA[<p>A current requirement is that assets uploaded to Amazon S3 must be accessed via SSL and use an expiring URL. Using an expiring url with Paperclip is extremely easy.</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; my_model.<span style="color:#9900CC;">image</span>.<span style="color:#9900CC;">expiring_url</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">5</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></div>
</pre>
<p>The problem is expiring_url doesn&#8217;t let you choose a style and doesn&#8217;t use https, which breaks our SSL site. To add the behaviour was an easy &#8220;hack&#8221;. I added the file /config/initializers/paperclip.rb with the following code:</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color:#9966CC; font-weight:bold;">module</span> Paperclip<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">module</span> Storage<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">module</span> S3<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">def</span> expiring_url<span style="color:#006600; font-weight:bold;">&#40;</span>style = default_style, time = <span style="color:#006666;">3600</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#6666ff; font-weight:bold;">AWS::S3::S3Object</span>.<span style="color:#9900CC;">url_for</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#40;</span>style<span style="color:#006600; font-weight:bold;">&#41;</span>, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bucket_name, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:expires_in</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> time, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:use_ssl</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
</pre>
<p>Now calling my expiring image URL with a style and over https is just:</p>
<pre>
<div class="codecolorer-container ruby vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; my_model.<span style="color:#9900CC;">image</span>.<span style="color:#9900CC;">expiring_url</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:original</span>, <span style="color:#006666;">5</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2010/12/07/paperclip-s3-expiring_url-with-styles-and-ssl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rspec/Cucumber Autotest Loop</title>
		<link>http://www.ur-ban.com/blog/2010/07/31/rspeccucumber-autotest-loop/</link>
		<comments>http://www.ur-ban.com/blog/2010/07/31/rspeccucumber-autotest-loop/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 19:33:25 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=1839</guid>
		<description><![CDATA[Autotest would constantly run my tests even though I hadn&#8217;t modified anything. Which made it impossible to actually use. Creating the following in a file called .autotest in my application&#8217;s root solved the problem for me. This is on Rails 3 RC, RSpec 2 beta 19 and Cucumber 0.8.5. &#160; Autotest.add_hook :initialize do &#124;at&#124; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Autotest would constantly run my tests even though I hadn&#8217;t modified anything. Which made it impossible to actually use. Creating the following in a file called .autotest in my application&#8217;s root solved the problem for me. This is on Rails 3 RC, RSpec 2 beta 19 and Cucumber 0.8.5.</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; Autotest.add_hook :initialize do |at|<br />
&nbsp; &nbsp; at.add_exception(%r{^\./\.git})<br />
&nbsp; &nbsp; at.add_exception(%r{^\./db})<br />
&nbsp; &nbsp; at.add_exception(%r{^\./log})<br />
&nbsp; &nbsp; at.add_exception(%r{^\./tmp})<br />
&nbsp; &nbsp; at.add_exception(%r{^\./rerun\.txt})<br />
&nbsp; &nbsp; at.add_exception(%r{^\./Gemfile\.lock})<br />
&nbsp; end</div></div>
</pre>
<pre><span style="font-family: monospace;"><strong>UPDATE: </strong>Updated with Wes' suggestion in the comments.</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2010/07/31/rspeccucumber-autotest-loop/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Thoughtbot Clearance &amp; mongomapper</title>
		<link>http://www.ur-ban.com/blog/2010/01/18/thoughtbot-clearance-mongo_mapper/</link>
		<comments>http://www.ur-ban.com/blog/2010/01/18/thoughtbot-clearance-mongo_mapper/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 22:09:14 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[mongodb]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=1345</guid>
		<description><![CDATA[Having a play with mongomapper and wanted to get Clearance working with it. Seemed to just be a simple case of doing the following in my user model. &#160; def self.attr_accessible(*args)end &#160; include Clearance::User My full user model ended up looking like this: &#160; class User &#160; &#160; include MongoMapper::Document &#160; &#160; def self.attr_accessible(*args)end &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Having a play with mongomapper and wanted to get Clearance working with it. Seemed to just be a simple case of doing the following in my user model.</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; def self.attr_accessible(*args)end<br />
&nbsp; include Clearance::User</div></div>
</pre>
<p>My full user model ended up looking like this:</p>
<pre>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; class User<br />
<br />
&nbsp; &nbsp; include MongoMapper::Document<br />
<br />
&nbsp; &nbsp; def self.attr_accessible(*args)end<br />
&nbsp; &nbsp; include Clearance::User<br />
<br />
&nbsp; &nbsp; key :email, String<br />
&nbsp; &nbsp; key :encrypted_password, String<br />
&nbsp; &nbsp; key :salt, String<br />
&nbsp; &nbsp; key :confirmation_token, String<br />
&nbsp; &nbsp; key :remember_token, String<br />
&nbsp; &nbsp; key :firstname, String<br />
&nbsp; &nbsp; key :email_confirmed, Boolean<br />
&nbsp; &nbsp; key :lastname, String<br />
<br />
&nbsp; &nbsp; timestamps!<br />
<br />
&nbsp; end</div></div>
</pre>
<p>Perhaps if I have time, I will look into adding attr_accessible support to mongomapper myself.</p>
<p><strong>Update 13/03/2010: </strong>I believe the dependency on attr_accessible in clearance has since been removed. So this small hack is most probably defunct.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2010/01/18/thoughtbot-clearance-mongo_mapper/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Law of Demeter and the delegate method</title>
		<link>http://www.ur-ban.com/blog/2009/10/25/law-of-demeter-and-the-delegate-method/</link>
		<comments>http://www.ur-ban.com/blog/2009/10/25/law-of-demeter-and-the-delegate-method/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 13:02:52 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[bestpractice]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=1193</guid>
		<description><![CDATA[The Law of Demeter, or Principle of Least Knowledge is a fairly simple design pattern, which, simply put means that an object should only talk to it&#8217;s immediate &#8220;friends&#8221; The law states that a method M of and object O may only invoke the methods of the following kind: 1. a method on O itself [...]]]></description>
			<content:encoded><![CDATA[<p>The Law of Demeter, or Principle of Least Knowledge is a fairly simple design pattern, which, simply put means that an object should only talk to it&#8217;s immediate &#8220;friends&#8221;</p>
<p>The law states that a method M of and object O may only invoke the methods of the following kind:</p>
<p>1. a method on O itself<br />
2. any parameters passed to M<br />
3. any objects instantiated within M<br />
4. any direct components of O</p>
<p>The classic example coined by David Bock used a Paperboy (one object) delivering a paper, then extracting money from a Customer&#8217;s (another object) Wallet (and another):</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Paperboy</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">customer</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="variable variable_language variable_language_ruby">self</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>money <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">+=</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>wallet<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>take_out<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>In the &#8220;real world&#8221; the Paperboy would ask the customer for the money who would then take it out for them, rather then the Paperboy reaching into the customer&#8217;s back pocket and getting it for themself.</p>
<p>Really we want something as follows:</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Paperboy</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">customer</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="variable variable_language variable_language_ruby">self</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>money <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">+=</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>get_payment<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Customer</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">amount</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      wallet<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>take_out<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>This may all seem trivial and a waste of time, but what happens if some Customers want to pay by cheque? Those decisions should have an impact on the Paperboy, otherwise we end up with:</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Paperboy</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">customer</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="keyword keyword_control keyword_control_ruby">if</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>pay_by_cash?
        <span class="variable variable_language variable_language_ruby">self</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>money <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">+=</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>wallet<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>take_out<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">elsif</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>pay_by_cheque?
        <span class="variable variable_language variable_language_ruby">self</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>money <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">+=</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>cheque_book<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>write_cheque<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">end</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>Where as it makes more sense for the change to be contained within the Customer:</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Paperboy</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">customer</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="variable variable_language variable_language_ruby">self</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>money <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_augmented keyword_operator_assignment_augmented_ruby">+=</span> customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>get_payment<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Customer</span></span>
    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">get_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">amount</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="keyword keyword_control keyword_control_ruby">if</span> pay_by_cash?
        wallet<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>take_out<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">elsif</span> pay_by_cheque?
        cheque_book<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>write_cheque<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_numeric constant_numeric_ruby">10</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">end</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>So what does this have to do with Rails and the delegate method? The delegate method adds a quick and simple way of following the Law of Demeter without having to do very much at all.</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Order</span></span>
    belongs_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Customer</span></span>
    has_many <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>orders</span>
    has_one <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>credit_card</span>
    has_one <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>bank_account</span>

    <span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">payment_method</span></span>
      <span class="keyword keyword_control keyword_control_ruby">if</span> pay_by_card?
        credit_card
      <span class="keyword keyword_control keyword_control_ruby">elsif</span> pay_by_account?
        bank_account
      <span class="keyword keyword_control keyword_control_ruby">end</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">CreditCard</span></span>
    belongs_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">BankAccount</span></span>
    belongs_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>This setup means to get an Order&#8217;s payment we would have to say:</p>
<pre class="textmate-source"><span class="source source_ruby">  <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>order</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>customer<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>payment_method<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>withdraw<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>amount<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span></span></pre>
<p>But if we simply change our objects as such:</p>
<pre class="textmate-source"><span class="source source_ruby"><span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Order</span></span>
    belongs_to <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer</span>
    delegate <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>withdraw_payment</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>to</span> <span class="punctuation punctuation_separator punctuation_separator_key-value">=&gt;</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>customer</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="meta meta_class meta_class_ruby">  <span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">Customer</span></span>
    has_many <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>orders</span>
    has_one <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>credit_card</span>
    has_one <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>bank_account</span>

    <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">withdraw_payment</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">amount</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
      <span class="keyword keyword_control keyword_control_ruby">if</span> pay_by_card?
        credit_card<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>withdraw<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>amount<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">elsif</span> pay_by_account?
        bank_account<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>withdraw<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>amount<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
      <span class="keyword keyword_control keyword_control_ruby">end</span>
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span></span></pre>
<p>Now all we have to say is:</p>
<pre class="textmate-source"><span class="source source_ruby">  <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>order</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>withdraw_payment<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>amount<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span></span></pre>
<p>So at any time, the details of how a payment  is to be decided can be contained with the Customer. This is of course a simplistic example, but hopefully explains how you chould be using this handy feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2009/10/25/law-of-demeter-and-the-delegate-method/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>rake spec fixtures failing</title>
		<link>http://www.ur-ban.com/blog/2009/08/06/rake-specdbfixturesload-failing-2/</link>
		<comments>http://www.ur-ban.com/blog/2009/08/06/rake-specdbfixturesload-failing-2/#comments</comments>
		<pubDate>Thu, 06 Aug 2009 12:02:38 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=1088</guid>
		<description><![CDATA[For some reason my rspec fixtures were not loading into my development database when doing spec:db:fixtures:load. An extra parameter to db:fixtures:load is all that’s needed. &#62;: rake spec:db:fixtures:load rake aborted! uninitialized constant Fixtures Fixed by: &#62;: rake db:fixtures:load FIXTURES_PATH=spec/fixtures]]></description>
			<content:encoded><![CDATA[<p>For some reason my rspec fixtures were not loading into my development database when doing spec:db:fixtures:load. An extra parameter to db:fixtures:load is all that’s needed.</p>
<pre class="textmate-source">
     &gt;: rake spec:db:fixtures:load
     rake aborted!
     uninitialized constant Fixtures
</pre>
<p>Fixed by:</p>
<pre class="textmate-source">
     &gt;: rake db:fixtures:load FIXTURES_PATH=spec/fixtures
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2009/08/06/rake-specdbfixturesload-failing-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails</title>
		<link>http://www.ur-ban.com/blog/2005/12/08/ruby-on-rails/</link>
		<comments>http://www.ur-ban.com/blog/2005/12/08/ruby-on-rails/#comments</comments>
		<pubDate>Thu, 08 Dec 2005 22:53:00 +0000</pubDate>
		<dc:creator>Richard</dc:creator>
				<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.ur-ban.com/blog/?p=78</guid>
		<description><![CDATA[So I began looking at Ruby on Rails a few days ago and I am quite impressed. To go from a database structure to a simple web app structure takes less then 15 minutes. Rails will generate a model and a controller for each of your database tables, or if you choose to generate a [...]]]></description>
			<content:encoded><![CDATA[<p>So I began looking at Ruby on Rails a few days ago and I am quite impressed. To go from a database structure to a simple web app structure takes less then 15 minutes. Rails will generate a model and a controller for each of your database tables, or if you choose to generate a scaffold, it will generate all the supporting rhtml for you instead of generating it on the fly.</p>
<p>I&#8217;ve got to get my head into it a bit more, so tonight I&#8217;m going to try setting up database associations and getting them to filter through, but from what I&#8217;ve read that shouldn&#8217;t be any problem at all.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ur-ban.com/blog/2005/12/08/ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.524 seconds -->

