<?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>Reggie&#039;s picayune</title>
	<atom:link href="http://nicholshayes.co.uk/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://nicholshayes.co.uk/blog</link>
	<description>Occasional wisdom, dispersed between reams of piffle</description>
	<lastBuildDate>Tue, 15 Nov 2011 10:50:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Output table column names to a file</title>
		<link>http://nicholshayes.co.uk/blog/?p=263</link>
		<comments>http://nicholshayes.co.uk/blog/?p=263#comments</comments>
		<pubDate>Tue, 15 Nov 2011 10:50:36 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=263</guid>
		<description><![CDATA[I&#8217;m working on tool to transfer data from one database to another. I wanted a list of column names in a file so that I had a list I could work through. After a hunt around the MySQL docs I found mysqlshow, which works a treat: &#160; mysqlshow -u username -p password database_name table_name &#62; [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on tool to transfer data from one database to another. I wanted a list of column names in a file so that I had a list I could work through. After a hunt around the MySQL docs I found <a href="http://dev.mysql.com/doc/refman/5.0/en/mysqlshow.html">mysqlshow</a>, which works a treat:</p>
<div class="codecolorer-container text default" 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; mysqlshow -u username -p password database_name table_name &gt; output.txt</div></div>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=263</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do not put hyphens in engine names</title>
		<link>http://nicholshayes.co.uk/blog/?p=256</link>
		<comments>http://nicholshayes.co.uk/blog/?p=256#comments</comments>
		<pubDate>Mon, 26 Sep 2011 10:40:38 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=256</guid>
		<description><![CDATA[I&#8217;m currently working on my first rails 3.1 engine and have just wasted a day or so because I put a hyphen in the engine name. The reason I did this was to be consistent with some other plug-ins I am using (e.g. noodall-core). The new plugin should provide polls for noodall sites. So noodall-poll [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently working on my first rails 3.1 engine and have just wasted a day or so because I put a hyphen in the engine name. The reason I did this was to be consistent with some other plug-ins I am using (e.g. <a href="https://github.com/reggieb/noodall-core">noodall-core</a>). The new plugin should provide polls for noodall sites. So noodall-poll would be consistent with other noodall plugins.</p>
<div class="codecolorer-container text default" 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">rails plugin new NoodallPoll --mountable</div></div>
<p>Created noodall_poll.</p>
<p>So instead I used:</p>
<div class="codecolorer-container text default" 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">rails plugin new noodall-poll --mountable</div></div>
<p>The result was lots of paths using noodall-poll, such as /app/helpers/noodall-poll/application_helper.rb. When I tried to run test, I got application_helper.rb not found errors. The system was looking for /app/helpers/noodall_poll/application_helper.rb.</p>
<p>Lesson learn: don&#8217;t play around with engine names. Use camelcase or underscored engine names.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=256</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My first gem: Acts As Soft Delete By Field</title>
		<link>http://nicholshayes.co.uk/blog/?p=247</link>
		<comments>http://nicholshayes.co.uk/blog/?p=247#comments</comments>
		<pubDate>Fri, 05 Aug 2011 22:17:09 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=247</guid>
		<description><![CDATA[I&#8217;ve had a bit of spare time recently, so I thought it was about time that I created a public gem. I thought about my code and decided that my soft delete system would be a good place to start. I&#8217;d created it about three years ago and it&#8217;s been used in a couple of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a bit of spare time recently, so I thought it was about time that I created a public gem. I thought about my code and decided that my soft delete system would be a good place to start. I&#8217;d created it about three years ago and it&#8217;s been used in a couple of corporate projects. It is also fairly simple and self contained.</p>
<p>It had been created in a somewhat pragmatic way, using the simplest way that I could find to implement it. That was to create the functionality in an ActiveRecord::Base abstract class, and then have all the models that needed this functionality, inherit this class. I&#8217;ve made the code available as <a href="https://github.com/reggieb/soft_deletable_base">SoftDeleteableBase</a>.</p>
<p>This approach works fine and is very easy to implement. The problem is that it does not scale very well. That is, if you need to add additional functionality in the same way, the new abstact class has to inherit from the original.</p>
<p>A much better way to add functionality to a model is by mixing in via a module. Having recently read <a href="http://www.informit.com/store/product.aspx?isbn=0321584104">Elequent Ruby</a> by Russ Olsen (my favourite Ruby author), and <a href="http://pragprog.com/book/ppmetr/metaprogramming-ruby">Metaprogramming Ruby</a> by Paolo Perrotta (the two books complement each other very well), I felt I should rewrite SoftDeletableBase as an &#8216;Act as&#8217; plugin.</p>
<p>The result was <a href="https://github.com/reggieb/acts_as_soft_delete_by_field">ActsAsSoftDeleteByField</a>. A bit verbose, but as <a href="https://github.com/cleanoffer/acts_as_soft_deletable">ActsAsSoftDeletable </a>already existed I needed to differentiate my plugin from that. ActsAsSoftDeletable moves deleted items into another table, which was not been the functionality I wanted. My system uses a field in the model&#8217;s table to flag when a record is deleted. A simple solution, but ActsAsSoftDeletable maybe more suitable for many projects.</p>
<p>The two books gave me the knowledge I needed to understand how the methods used to create the mixin can be used. However, I found it very useful to look at other Acts As plugins such as acts_as_rateable, and acts_as_nested_set, to see how to arrange the code. The <a href="http://guides.rubyonrails.org/plugins.html">Ruby on Rails Guide</a> was also useful.</p>
<p>Loading instance and class methods is actually fairly straight forward. Most of the work is done by this bit of code:</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">included</span><span style="color:#006600; font-weight:bold;">&#40;</span>base<span style="color:#006600; font-weight:bold;">&#41;</span><br />
   base.<span style="color:#9900CC;">send</span> <span style="color:#ff3333; font-weight:bold;">:extend</span>, ClassMethods<br />
&nbsp;<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Getting the code to load properly was more difficult. It took me a little fiddling to get the init.rb file to work correctly. A lot of examples use class_eval here, but as I know the class names, I chose to use the simpler technique of monkey patching:</p>
<div class="codecolorer-container ruby default" 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">$:.<span style="color:#9900CC;">unshift</span> <span style="color:#996600;">&quot;#{File.dirname(__FILE__)}/lib&quot;</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'soft_delete_by_field'</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">ActiveSupport::TestCase</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> ActsAsSoftDeleteByFieldAssertions<br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Acts::SoftDeleteByField</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>I used a set of assertions I&#8217;d used to test SoftDeleteableBase to test the new mixin, and included this code in the new plugin. That made it a lot easier to check the functionality. I created a new Rails app, and generated a Thing model. I then applied acts_as_soft_delete_by_field to thing, made sure it had a :deleted_at field, and ran the tests.</p>
<p>The next thing I did was to extend the functionality so that an alternative field could be used to store the deleted information. A few modifications and that was all working.</p>
<p>The last step was to create the gem. Russ Olsen&#8217;s book gave me the basics. The main thing that caused me problems was again initiating the script. </p>
<p>The main problem is that many of the examples on the web use the old system relying on /rails/init.rb, but I couldn&#8217;t get this to work. In the end, I realised that a file with the gem name was always loaded, and therefore that would be the place to put the hook script. So acts_as_soft_delete_by_field.rb was created and I put a hook script there. With that in place everything started working a treat.</p>
<p>The end result was the acts_as_soft_delete_by_field gem! </p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=247</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Geek&#8217;s take on dealing with stress</title>
		<link>http://nicholshayes.co.uk/blog/?p=236</link>
		<comments>http://nicholshayes.co.uk/blog/?p=236#comments</comments>
		<pubDate>Mon, 09 May 2011 13:26:28 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Bereavement support]]></category>
		<category><![CDATA[Community First Responder]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=236</guid>
		<description><![CDATA[Being a CFR has put me in stressful situations. Trying to resusitate someone with kith and kin look on, is demanding.* Last year I also started work carrying out bereavement support for a local hospice. The training involved in getting me up to speed in this work, has made me think a lot about how [...]]]></description>
			<content:encoded><![CDATA[<p><em>Being a CFR has put me in stressful situations. Trying to resusitate someone with kith and kin look on, is demanding.*</p>
<p>Last year I also started work carrying out bereavement support for a local hospice. The training involved in getting me up to speed in this work, has made me think a lot about how we behave in stressful situations such as bereavement.</p>
<p>Of course, I&#8217;m also a geek. Ruby programmer is my day job after all.</p>
<p>With all that in mind, here is my take on very stressful occurrences such as bereavement:</em></p>
<p><strong>Bereavement: UDP and the unconcious mind</strong></p>
<p>Your brain works very like a UDP <a href="http://www.tcpipguide.com/free/t_TCPIPArchitectureandtheTCPIPModel-2.htm">stack</a>, where the conscious mind sits at the application layer.</p>
<p>Most of the work is done within lower parts of the stack, and with everything working normally, stuff gets passed down into the unconscious brain and stuff pops back up without the top layer knowing or really caring about what happened lower down. You often think your conscious mind is doing all the work, but actually its all happening lower down.</p>
<p>Normally, the stack is able to handle problems and routes messages back and forth without any problem.</p>
<p>However, when something very stressful happens the stack gets disrupted. It gets information it doesn&#8217;t know how to handle. The result at the top layer is it doesn&#8217;t get any answers. Also as this is <a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol">UDP</a>, it doesn&#8217;t get any error messages either. So the net result is numb confusion.</p>
<p>With time the stack fixes itself. This can take hours or even days. Until then nothing computes properly. You can&#8217;t concentrate, you feel numb, and a little confused because you can&#8217;t figure out what is happening. These symptoms only go away once the stack fixes itself and normal conscious to sub-conscious communication returns.</p>
<p>This matches my experience:</p>
<p>Immediately after a very stressful situation I am left with a very numb, empty feeling where my brain just doesn&#8217;t work normally. The only thing that fixes this is time. I&#8217;ve learnt to recognise this feeling and the knowledge that time fixes it helps me deal with it. Trying to force my brain to fix the problem just makes the fix time longer.</p>
<p>Once the stack sorts itself out (for me, 2 to 12 hours is a common fix time), I can then start the rational process of sorting out the emotions and images that pop into my head.</p>
<hr />
<small>* In fact, I find the reactions of relatives stick in my mind far longer than what actually happened to the patient or what I did. For example, the image of a wife crying at the bottom of the stairs is my main memory of a particular CPR attempt.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=236</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Model inhertiance</title>
		<link>http://nicholshayes.co.uk/blog/?p=232</link>
		<comments>http://nicholshayes.co.uk/blog/?p=232#comments</comments>
		<pubDate>Thu, 27 Jan 2011 14:46:18 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=232</guid>
		<description><![CDATA[I&#8217;m working on an application with some CMS features. One requirement is that new content is moderated before being published. To enable this, some users are allocated as moderators. To achieve this I have a moderator status column which can be either &#8216;some&#8217; or &#8216;all&#8217; (at the moment a &#8216;some&#8217; moderator can only moderate content [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on an application with some CMS features. One requirement is that new content is moderated before being published. To enable this, some users are allocated as moderators. To achieve this I have a moderator status column which can be either &#8216;some&#8217; or &#8216;all&#8217; (at the moment a &#8216;some&#8217; moderator can only moderate content in some languages). Up until now it hasn&#8217;t be too cumbersome to have user methods associated with moderaters defined within the User class, but now I&#8217;m getting to the point where it would be good to split some of this functionality out into a separate class.</p>
<p>My problem was how to connect a new Moderator class to the User class. </p>
<p>A starting point is that I want Moderator class to inherit from User. That&#8217;s simple:</p>
<div class="codecolorer-container ruby default" 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">Moderator <span style="color:#006600; font-weight:bold;">&lt;</span> User<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>The problem with this is if you do Moderator.find(:all) you get all users and not just those who are moderators.</p>
<p>In my last project, I overrode find, but that was a Rails 2 project and the same technique doesn&#8217;t work so well for this Rails 3 project. For example, Moderator.all still returns all users.</p>
<p>Another option would be to use &#8216;Single Table Inheritance&#8217; (see <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">ActiveRecord::Base api</a>), but that would mean adding a new field and then limiting users to just one sub-class. For example, I think I will use the same technique with admins, and what if a moderator is both a moderator and an admin. Single Table Inheritance won&#8217;t let you do that.</p>
<p>In the end the solution was ridiculous simple. It is <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html#method-c-default_scope">&#8216;default_scope&#8217;</a>.</p>
<p>This works</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#9966CC; font-weight:bold;">class</span> Moderator <span style="color:#006600; font-weight:bold;">&lt;</span> User<br />
&nbsp; default_scope where<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;moderation_scope IN (?)&quot;</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'all'</span>, <span style="color:#996600;">'some'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>And this is what I ended up with:</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><br />
<br />
&nbsp; MODERATE_ALL_SCOPE = <span style="color:#996600;">'all'</span><br />
&nbsp; MODERATE_SOME_SCOPE = <span style="color:#996600;">'some'</span><br />
&nbsp; MODERATION_SCOPES = <span style="color:#006600; font-weight:bold;">&#91;</span>MODERATE_ALL_SCOPE, MODERATE_SOME_SCOPE<span style="color:#006600; font-weight:bold;">&#93;</span> <br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_moderators</span><br />
&nbsp; &nbsp; where<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;moderation_scope IN (?)&quot;</span>, MODERATION_SCOPES<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">class</span> Moderator <span style="color:#006600; font-weight:bold;">&lt;</span> User<br />
&nbsp; default_scope find_moderators<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>If I have special data entries that alter behaviour, I prefer to put them into constants and use the constants within the code. That way I can change the specific data entries at a later date without having to change every instance where it is used. Hence using MODERATION_SCOPES.</p>
<p>The final version also allows me to share the same code between User.find_moderators and Moderator.default_scope.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=232</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mongrel_service on Windows 7 64bit</title>
		<link>http://nicholshayes.co.uk/blog/?p=227</link>
		<comments>http://nicholshayes.co.uk/blog/?p=227#comments</comments>
		<pubDate>Mon, 25 Oct 2010 10:39:54 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=227</guid>
		<description><![CDATA[My current applications run on Linux in production, but I still develop on Windows PCs. My main works PC runs Windows 7 Pro 64bit. This isn&#8217;t too much of a problem. Just a couple of things don&#8217;t work (like wicked_pdf), but I can fire up a VirtualBox Linux image and test via that when I [...]]]></description>
			<content:encoded><![CDATA[<p>My current applications run on Linux in production, but I still develop on Windows PCs. My main works PC runs Windows 7 Pro 64bit. This isn&#8217;t too much of a problem. Just a couple of things don&#8217;t work (like wicked_pdf), but I can fire up a VirtualBox Linux image and test via that when I need to.</p>
<p>However, I needed to provide a production version of one of my applications for a colleague writing some documentation. In the past running a mongrel instance as a service on my PC has been great for this, but having recently upgraded to Rails 3, I&#8217;ve managed to kill my mongrel_service gem. Unfortunately reinstalling was not as easy as I thought. To get it to work I had to do the following:</p>
<p>Install win32-service separately and force it to install the binary version rather than build it from source. To do that:</p>
<div class="codecolorer-container text default" 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">gem install win32-service --platform x86-mswin32</div></div>
<p>Notice the double dash before platform. The <a href="http://jwwishart.wordpress.com/2010/06/21/mongrel-rails-on-windows-7/">blog where I first got this from</a> had only one dash which caused me a little head scratching.</p>
<p>Then I had to install the &#8216;pre&#8217; version of mongrel_service:</p>
<div class="codecolorer-container text default" 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">gem install mongrel_service --pre</div></div>
<p>I found that step from <a href="http://www.mail-archive.com/mongrel-users@rubyforge.org/msg05908.html">this blog</a>.</p>
<p>BTW, I run a command prompt as the administrator when running gem commands (right click cmd icon and select &#8216;run as administrator&#8217;) </p>
<p>Once that was done I could use the mongrel_service as usual:</p>
<div class="codecolorer-container text default" 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">C:\Windows\system32&gt;mongrel_rails service::install -N OLM_demo \ -c C:\web\public_site\olm -p 8001 -e production</div></div>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=227</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time format</title>
		<link>http://nicholshayes.co.uk/blog/?p=223</link>
		<comments>http://nicholshayes.co.uk/blog/?p=223#comments</comments>
		<pubDate>Thu, 07 Oct 2010 14:18:24 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=223</guid>
		<description><![CDATA[I found an interesting article by Todd Sayre on time formats in Rails. It is only short, but interesting. Based on that I created config/initializers/time_formats.rb in my latest app: # Used to create time and datetime formatting short cuts. Search for to_formatted_s in the api # Also see http://snippets.dzone.com/posts/show/2406 # If date = Time.local(2009,12,24,15,30,27) Time::DATE_FORMATS&#91;:datetime&#93; [...]]]></description>
			<content:encoded><![CDATA[<p>I found an <a href="http://snippets.dzone.com/posts/show/2406">interesting article by Todd Sayre</a> on time formats in Rails. It is only short, but interesting. Based on that I created config/initializers/time_formats.rb in my latest app:</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#008000; font-style:italic;"># Used to create time and datetime formatting short cuts. Search for to_formatted_s in the api</span><br />
<span style="color:#008000; font-style:italic;"># Also see http://snippets.dzone.com/posts/show/2406</span><br />
<br />
<span style="color:#008000; font-style:italic;"># If date = Time.local(2009,12,24,15,30,27)</span><br />
<br />
<span style="color:#CC00FF; font-weight:bold;">Time</span>::DATE_FORMATS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:datetime</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;%d-%b-%Y %H:%M&quot;</span> &nbsp;<span style="color:#008000; font-style:italic;"># date.to_s(:datetime) &nbsp;----&gt; &nbsp;24-Dec-2009 15:30</span><br />
<span style="color:#CC00FF; font-weight:bold;">Time</span>::DATE_FORMATS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:date</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;%d-%b-%Y&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;"># date.to_s(:date) &nbsp; &nbsp; &nbsp;----&gt; &nbsp;24-Dec-2009</span><br />
<span style="color:#CC00FF; font-weight:bold;">Time</span>::DATE_FORMATS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:time</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;%H:%M&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># date.to_s(:time) &nbsp; &nbsp; &nbsp;----&gt; &nbsp;15:30</span><br />
<span style="color:#CC00FF; font-weight:bold;">Time</span>::DATE_FORMATS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:default</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC00FF; font-weight:bold;">Time</span>::DATE_FORMATS<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:datetime</span><span style="color:#006600; font-weight:bold;">&#93;</span> &nbsp; <span style="color:#008000; font-style:italic;"># Sets default behaviour for date.to_s</span></div></div>
<p>I think the code speaks for itself. As you can see it is very easy to extend Time#to_s to provide straight forward formatting. It is also easy to overwrite the default</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=223</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logging activity within a Rails application</title>
		<link>http://nicholshayes.co.uk/blog/?p=213</link>
		<comments>http://nicholshayes.co.uk/blog/?p=213#comments</comments>
		<pubDate>Thu, 27 May 2010 10:53:50 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.co.uk/blog/?p=213</guid>
		<description><![CDATA[I wanted to add a tool to log users&#8217; activity in my current application. I wanted something simple, and decided that the solution was to combine two techniques: One: making session data available at the model and observer level. An article by Geoff Lane gave me the information I needed to be able to achieve [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to add a tool to log users&#8217; activity in my current application. I wanted something simple, and decided that the solution was to combine two techniques:</p>
<p>One: making session data available at the model and observer level. <a href="http://www.zorched.net/2007/05/29/making-session-data-available-to-models-in-ruby-on-rails/">An article by Geoff Lane</a> gave me the information I needed to be able to achieve that.</p>
<p>Two: use an observer to catch Model call backs and trigger an action in response. The Rails api documentation gave me the information I needed on creating an <a href="http://api.rubyonrails.org/classes/ActiveRecord/Observer.html">observer</a>.</p>
<p>Here is a simple example as to how I was able to add an activity logger using these two techniques.</p>
<p>First I created a new module:</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#9966CC; font-weight:bold;">module</span> MakeUserAvailableViaThread<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> user_in_thread<br />
&nbsp; &nbsp; <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">user_in_thread</span>=<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span> = user<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>This was based on Geoff Lane&#8217;s UserInfo module. I made two changes: I used a more descriptive module name; and I changed the method name because current_user was already used in the controller by my authentication system (&#8216;restful_authentication&#8217;). The later stopped me logging in successfully until I spotted the problem.</p>
<p>I then added these two lines to my ApplicationController:</p>
<div class="codecolorer-container ruby default" 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;">include</span> MakeUserAvailableViaThread<br />
&nbsp; before_filter <span style="color:#ff3333; font-weight:bold;">:pass_current_user_to_thread_where_it_can_be_seen_by_observer</span></div></div>
<p>Together with this private method:</p>
<div class="codecolorer-container ruby default" 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;">def</span> pass_current_user_to_thread_where_it_can_be_seen_by_observer<br />
&nbsp; &nbsp; MakeUserAvailableViaThread.<span style="color:#9900CC;">user_in_thread</span> = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>So very similar to Geoff Lane&#8217;s code except with more descriptive method names.</p>
<p>I then needed to add the observer:</p>
<div class="codecolorer-container ruby default" 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"><span style="color:#9966CC; font-weight:bold;">class</span> ActivityLogger <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Observer</span><br />
&nbsp; observe <span style="color:#ff3333; font-weight:bold;">:account</span>, <span style="color:#ff3333; font-weight:bold;">:license</span><br />
&nbsp; <br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> MakeUserAvailableViaThread<br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> after_update<span style="color:#006600; font-weight:bold;">&#40;</span>record<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;HEY! something changed: #{user_in_thread.full_name if user_in_thread} altered #{record.class.to_s} #{record.id}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> after_create<span style="color:#006600; font-weight:bold;">&#40;</span>record<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;HEY! something changed: #{user_in_thread.full_name if user_in_thread} created #{record.class.to_s} #{record.id}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>However, nothing happened until I added this line to config/environment.rb:</p>
<div class="codecolorer-container ruby default" 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">config.<span style="color:#9900CC;">active_record</span>.<span style="color:#9900CC;">observers</span> = <span style="color:#ff3333; font-weight:bold;">:activity_logger</span></div></div>
<p>Note that config.active_record.observers only gets called at application start, so you may need to stop and start your application before the observer starts working.</p>
<p>I now have a system I can extend to log activity. As shown above, only changes to accounts and licenses are logged, and the log just outputs to the console at the moment. However, now I have the mechanism, it is easy to create a new ActivityLog model and save the log entries to that in whatever format I fancy.</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=213</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>attachment_fu &#8211; working with database file storage</title>
		<link>http://nicholshayes.co.uk/blog/?p=199</link>
		<comments>http://nicholshayes.co.uk/blog/?p=199#comments</comments>
		<pubDate>Tue, 18 May 2010 14:33:42 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.myzen.co.uk/blog/?p=199</guid>
		<description><![CDATA[Once I had attachment_fu working with files stored within the Rails application file system, I hit a problem as I wanted to be able to share files across three applications. The problem being that if the file was uploaded in one application, it would be stored within that application&#8217;s public folder. Without adding complication, this [...]]]></description>
			<content:encoded><![CDATA[<p>Once I had attachment_fu working with files stored within the Rails application file system, I hit a problem as I wanted to be able to share files across three applications. The problem being that if the file was uploaded in one application, it would be stored within that application&#8217;s public folder. Without adding complication, this location wasn&#8217;t available to the other applications.</p>
<p>The solution was to change over to storing the files within the database. This took a couple of small modifications:</p>
<p><strong>model</strong><br />
I changed the has_attachment declaration to:</p>
<div class="codecolorer-container ruby default" 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">has_attachment <span style="color:#ff3333; font-weight:bold;">:max_size</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">50</span>.<span style="color:#9900CC;">megabyte</span></div></div>
<p>The default attachment_fu is to use the database to store files. So removing the :storage entry in this statement was enough to change over from file system storage to database storage.</p>
<p><strong>database</strong><br />
I has to add a new table and an additional column to my main model. The new table was created with:</p>
<div class="codecolorer-container ruby default" 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; &nbsp; create_table <span style="color:#ff3333; font-weight:bold;">:db_files</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:data</span>, <span style="color:#ff3333; font-weight:bold;">:binary</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">50</span>.<span style="color:#9900CC;">megabyte</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Note that adding a :limit entry can alter the blob field type created in the database. Without it the standard MySQL behaviour is to create an ordinary blob field. If the :limit statement indicated that a blob isn&#8217;t big enough, the data field will be set as a LONGBLOB.</p>
<p>The extra field added to my product_files table was &#8216;db_file_id&#8217; which is an integer field.</p>
<p><b>public_filename</b><br />
When working with database file storage, public_filename is no longer available. So I needed to come up with an alternative way to serve the file to the user. </p>
<p><b>controller download action</b><br />
To do this I created a download action.</p>
<div class="codecolorer-container ruby default" 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;">def</span> download<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">and</span> ProductFile.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; product_file = ProductFile.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; send_data<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; product_file.<span style="color:#9900CC;">current_data</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> product_file.<span style="color:#9900CC;">content_type</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:filename</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> product_file.<span style="color:#9900CC;">filename</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Product file not found&quot;</span><br />
&nbsp; &nbsp; &nbsp; redirect_to <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'index'</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>
<p>Note that send_data is a standard Rails method, so its use can be looked up in the <a href="http://api.rubyonrails.com">Rails api</a>. I wasted a little time trying to find this in the attachment_fu code.</p>
<p><b>helper</b><br />
It was then just a case of creating a helper that pointed at this action.</p>
<div class="codecolorer-container ruby default" 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;">def</span> link_to_download<span style="color:#006600; font-weight:bold;">&#40;</span>product_file<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; link_to<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">'Download'</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'product_files'</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'download'</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> product_file.<span style="color:#9900CC;">id</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p><b>view</b><br />
This could then be used in a view, wherever I need a link to download a file I used it like this:</p>
<div class="codecolorer-container ruby default" 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:#006600; font-weight:bold;">&lt;%</span>= link_to_download<span style="color:#006600; font-weight:bold;">&#40;</span>@product_file<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></div></div>
<p>Job done (except writing the tests of course)</p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=199</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing attachment_fu</title>
		<link>http://nicholshayes.co.uk/blog/?p=176</link>
		<comments>http://nicholshayes.co.uk/blog/?p=176#comments</comments>
		<pubDate>Fri, 14 May 2010 12:03:51 +0000</pubDate>
		<dc:creator>Rob Nichols</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://nicholshayes.myzen.co.uk/blog/?p=176</guid>
		<description><![CDATA[I&#8217;m working on a portion of my latest application that will need a facility to upload files. As these files are not images, I decided to use the plug-in attachment_fu. The thing that has caused me the most head scratching was how to set up unit tests to work with attachment_fu. The class stores files [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a portion of my latest application that will need a facility to upload files. As these files are not images, I decided to use the plug-in <a href="http://wiki.github.com/technoweenie/attachment_fu/">attachment_fu</a>. The thing that has caused me the most head scratching was how to set up unit tests to work with attachment_fu.</p>
<p>The class stores files related to a product. These are either code exerts or documentation. I&#8217;ve called the class ProductFile.</p>
<h3>Params</h3>
<p>If you are going to run tests that pass in data via a params hash, how do you get a file into the params in the right format. Here is the solution I worked out:</p>
<div class="codecolorer-container ruby default" 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">test_file_path = <span style="color:#6666ff; font-weight:bold;">ActionController::TestCase</span>.<span style="color:#9900CC;">fixture_path</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/files/test.txt'</span><br />
test_file = <span style="color:#6666ff; font-weight:bold;">ActionController::TestUploadedFile</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>test_file_path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#0066ff; font-weight:bold;">@product_file_params</span> = <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; product_id <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1</span>,<br />
&nbsp; <span style="color:#ff3333; font-weight:bold;">:document_type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'document'</span>,<br />
&nbsp; <span style="color:#ff3333; font-weight:bold;">:version</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">2</span>,<br />
&nbsp; <span style="color:#ff3333; font-weight:bold;">:uploaded_data</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> test_file<br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>I couldn&#8217;t get this to work without having the test file in a sub-folder of the fixtures folder. So I added a file &#8216;test/fixtures/files/test.txt&#8217;. Then I used ActionController::TestCase.fixture_path to determine the path.</p>
<h3>Tear down</h3>
<p>The other problem I had was that the standard Rails unit test tear down process wasn&#8217;t removing files created during the test. I overcame this by keeping track of each ProductFile created during the tests, and then using a teardown method to remove them all at the end of the test. This is the code that achieved that:</p>
<div class="codecolorer-container ruby default" 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">@@created_product_files = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">def</span> create_product_file_from_params<span style="color:#006600; font-weight:bold;">&#40;</span>params_mod = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; product_file = ProductFile.<span style="color:#9900CC;">create</span><span style="color:#006600; font-weight:bold;">&#40;</span>@product_file_params.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span>params_mod<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; @@created_product_files <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> product_file<br />
&nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> product_file<br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">def</span> teardown<br />
&nbsp; remove_product_files_created_during_test<br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">def</span> remove_product_files_created_during_test<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">for</span> product_file <span style="color:#9966CC; font-weight:bold;">in</span> @@created_product_files<br />
&nbsp; &nbsp; product_file.<span style="color:#9900CC;">destroy</span> <span style="color:#9966CC; font-weight:bold;">if</span> product_file.<span style="color:#9900CC;">filename</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Now, as long as I used the create_product_file_from_params to create new product_files with params, the test would clean up after itself.</p>
<h3>Fixtures</h3>
<p>By the way, Product Files created via fixtures didn&#8217;t create a matching file in the file system. Which make it easier to keep things tidy, but needs to be kept in mind if you need an actual file to test against.</p>
<h3>References</h3>
<p><a href="http://wiki.github.com/technoweenie/attachment_fu/">attachment_fu wiki</a></p>
<p><a href="http://clarkware.com/cgi/blosxom/2007/02/24#FileUploadFu&#038;gt">Mike Clark&#8217;s example of using attachment_fu</a></p>
<p><a href="http://unixmonkey.net/?p=18">David Jones&#8217; very interesting article on using attachment_fu with acts_as_versioned</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nicholshayes.co.uk/blog/?feed=rss2&#038;p=176</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

