<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-gb"><title type="text">JustinFrench.com - notebook</title>
<subtitle type="text">Web Application Design, Development and Related Geekery</subtitle>

<link rel="alternate" type="text/html" href="http://justinfrench.com/" />
<id>tag:justinfrench.com,2005:083bed6ad50451eb341a307b6c00ee12/notebook</id>
<generator uri="http://textpattern.com/" version="4.0.3">Textpattern</generator>
<updated>2012-01-29T22:17:04Z</updated>
<author>
		<name>Justin French</name>
		<email>justin.french@indent.com.au</email>
		<uri>http://justinfrench.com/</uri>
</author>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/justinfrench" /><feedburner:info uri="justinfrench" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2012-01-29T21:16:00Z</published>
		<updated>2012-01-29T22:17:04Z</updated>
		<title>A Better iPhone Mute Switch</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/e8LZvebWCXw/a-better-iphone-mute-switch" />
		<id>tag:justinfrench.com,2012-01-29:083bed6ad50451eb341a307b6c00ee12/6fd54a970ccaca515bf0ea6cda8add84</id>
		<category term="Design" />
		<category term="Apple" />
		<content type="html">
	&lt;p&gt;Two weeks back, many of my favorite tech bloggers were covering the story of a &lt;a href="http://www.nytimes.com/2012/01/13/nyregion/ringing-finally-stopped-but-concertgoers-alarm-persists.html?_r=1"&gt;switched-off iPhone’s alarm stopping a performance at the New York Philharmonic&lt;/a&gt;.&lt;/p&gt;
	&lt;h3&gt;It should be smart!&lt;/h3&gt;
	&lt;p&gt;&lt;a href="http://daringfireball.net/2012/01/iphone_mute_switch_design"&gt;John Gruber argued&lt;/a&gt; that this is an edge case—while Apple’s design is more complicated than simple “Off” and “Mute” switches, it’s far more likely to do what the user expects in most cases:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;I think the current behavior of the iPhone mute switch is correct. [...] if the mute switch silenced everything, there’d be thousands of people oversleeping every single day because they went to bed the night before unaware that the phone was still in silent mode.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I mostly agree with this sentiment.&lt;/p&gt;
	&lt;h3&gt;It should be dumb!&lt;/h3&gt;
	&lt;p&gt;&lt;a href="http://ihnatko.com/2012/01/14/daring-fireball-on-the-behavior-of-the-iphone-mute-switch/"&gt;Andy Ihnatko argues&lt;/a&gt; that Apple’s design made it hard for the user to prevent the interruption:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;No. I should slide the switch to “Mute,” and then the phone goes SILENT. If I miss an appointment because I did that, it’s completely on me. If my phone disrupts a performance despite the fact that I took clear and deliberate action to prevent that from happening…that’s the result of sloppy design. Or arrogant design, which is harder to forgive.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;My phone is almost always switched into silent mode (usually deliberately), and I rely on the alarm to wake me every day. The interesting thing here is that I &lt;em&gt;learned&lt;/em&gt; that this is how the iPhone works, and have now become accustomed to it. If &lt;em&gt;I&lt;/em&gt; interrupted this performance, I’d argue that the fault was completely on me—I could have ensured that there were no active alarms, or left the phone at home.&lt;/p&gt;
	&lt;p&gt;In the case of the Philharmonic, this was a brand new iPhone, and the owner learned the hard way how it works. It’s hard not to fault Apple here, despite Apple’s overall design being much better most of the time.&lt;/p&gt;
	&lt;h3&gt;Recap&lt;/h3&gt;
	&lt;p&gt;Here’s the requirements I’m hearing so far:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;It would suck to miss an important alarm, no matter who is at fault&lt;/li&gt;
		&lt;li&gt;It would suck to be that guy, no matter who was at fault&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;As &lt;a href="http://www.marco.org/2012/01/14/mute"&gt;Marco Arment succinctly points out&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;The user has issued conflicting commands, and the iPhone can’t obey both.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;h3&gt;What about a preference?&lt;/h3&gt;
	&lt;p&gt;&lt;a href="http://hivelogic.com/articles/mute/"&gt;Dan Benjamin also argued for a dumb switch&lt;/a&gt;, but in a later update, raised the idea of a preference:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Know what would be really cool? Let users decide for themselves what the switch does. They could call it a “side switch” like they do on the iPad, and give us choices about what it controls.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;A preference or user configuration is a pretty obvious and valid design crutch when faced with requirements that contradict each other so drastically, but in this case, I think it raises more questions:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;What would the default preference be? If it defaulted to Apple’s existing behavior, the conductor was still going to get interrupted, and if it was the other way around, I would have missed quite a few important alarms by now.&lt;/li&gt;
		&lt;li&gt;As they choose their preference, would users understand the design trade-offs and spend as much time thinking about this as Apple, John, Andy, Dan, you or I have?&lt;/li&gt;
		&lt;li&gt;Would this preference still result in people being surprised and disappointed?&lt;/li&gt;
	&lt;/ol&gt;
	&lt;h3&gt;What else could we do?&lt;/h3&gt;
	&lt;p&gt;I think Apple has solved &lt;em&gt;most&lt;/em&gt; of the problems already with a great design – the alarm does the right thing in the majority of use cases. At this point, with millions of iPhone customers now relying on how this stuff already works, it would be a shame to either go back to something &lt;em&gt;dumb&lt;/em&gt; or offer a preference between &lt;em&gt;smart&lt;/em&gt; and &lt;em&gt;dumb&lt;/em&gt; without first answering a simple question:&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Given this new information, could we improve the experience by making the smart stuff &lt;em&gt;smarter&lt;/em&gt;, instead of &lt;em&gt;dumber&lt;/em&gt; or &lt;em&gt;configrable&lt;/em&gt;?&lt;/strong&gt;&lt;/p&gt;
	&lt;p&gt;I think the answer is &lt;em&gt;yes&lt;/em&gt;! Let’s take a look at those two opposing requirements again:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;It would suck to miss an important alarm, no matter who is at fault&lt;/li&gt;
		&lt;li&gt;It would suck to be that guy, no matter who was at fault&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;What about this: When the iPhone is in “silent” mode, all alarms start off with vibration only. After a minute or so, the audio gradually fades in, increasing to full volume over the course of another two minutes.&lt;/p&gt;
	&lt;p&gt;Most mornings, I think the vibration of my iPhone alone would be enough to wake me. If not, I’d much prefer I wake up a few minutes later than completely miss the alarm because of a dumb switch (or a dumb user!). I think this satisfies this first requirement just fine.&lt;/p&gt;
	&lt;p&gt;For the second requirement, &lt;em&gt;that guy&lt;/em&gt; would have had 60 seconds of silent vibration in his pocket to realise something’s going on, and another 60–120 seconds before the alarm was at full volume. Not as perfect as a &lt;em&gt;dumb&lt;/em&gt; switch, but a significant improvement.&lt;/p&gt;
	&lt;p&gt;Maybe I’ve missed something, maybe it’s already been mentioned elsewhere, maybe it’s already built and tested by Apple, but this sure is an interesting design problem I enjoyed thinking though over the weekend!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/e8LZvebWCXw" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/a-better-iphone-mute-switch</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2012-01-17T22:05:00Z</published>
		<updated>2012-01-17T22:05:53Z</updated>
		<title>Formtastic 2.1.0.beta1 Released</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/XcMEUNA9Inc/formtastic-210beta1-released" />
		<id>tag:justinfrench.com,2012-01-17:083bed6ad50451eb341a307b6c00ee12/ed2a8c3f1ba22ffb73e4235f60b6253f</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;Putting this release together has been a lot of fun. We added &lt;a href="https://github.com/haines"&gt;Andrew Haines&lt;/a&gt; to the core team after a few stellar patches improving documentation and refactoring internals, and the sheer number of pull requests (from tiny documentation changes, through to epic commits) we’re seeing is absolutely fantastic.&lt;/p&gt;
	&lt;p&gt;The &lt;a href="http://rubygems.org/gems/formtastic"&gt;Formtastic 2.1.0.beta1 gem is now available on RubyGems.org&lt;/a&gt;, compatible with Rails 3.0.x, 3.1.x and 3.2.x (3.2.0.rc2 at the time of writing).&lt;/p&gt;
	&lt;h3&gt;New Features&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Added Rails 3.2 compatibility&lt;/li&gt;
		&lt;li&gt;Added a new Actions DSL (&lt;code&gt;f.actions&lt;/code&gt;, &lt;code&gt;f.action&lt;/code&gt;) — see below for deprecation of the Buttons DSL&lt;/li&gt;
		&lt;li&gt;Added new &lt;code&gt;i18n_localizer&lt;/code&gt; configuration, allowing you to use your own localiser class instead of &lt;code&gt;Formtastic::Localizer&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Added a hidden input before mutli-selects, to allow full clearing of the select (like we do for checkboxes)&lt;/li&gt;
		&lt;li&gt;Added support for integers in a &lt;code&gt;:collection&lt;/code&gt; for &lt;code&gt;radio&lt;/code&gt; and &lt;code&gt;check_boxes&lt;/code&gt; inputs&lt;/li&gt;
		&lt;li&gt;Added support for time inputs with no current value to default render blank inputs rather than pre-selecting the current time&lt;/li&gt;
		&lt;li&gt;Brought back the Form Generator from 1.2.x versions of Formtastic&lt;/li&gt;
		&lt;li&gt;Added support for placeholder text on textareas (&lt;code&gt;text&lt;/code&gt; inputs)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Deprecations&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Deprecated the Buttons DSL (&lt;code&gt;f.buttons&lt;/code&gt;, &lt;code&gt;f.commit_button&lt;/code&gt;) in favor of the new Actions DSL — see above&lt;/li&gt;
		&lt;li&gt;Removed the previously deprecated &lt;code&gt;:label_method&lt;/code&gt;, &lt;code&gt;:value_method&lt;/code&gt; &amp; &lt;code&gt;:group_label_method&lt;/code&gt; options&lt;/li&gt;
		&lt;li&gt;Removed the previously deprecated &lt;code&gt;:as =&amp;gt; :numeric&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Removed the previously deprecated &lt;code&gt;inline_errors_for&lt;/code&gt; and related methods&lt;/li&gt;
		&lt;li&gt;Removed the previously deprecated &lt;code&gt;SemanticFormHelper&lt;/code&gt; and &lt;code&gt;SemanticFormBuilder&lt;/code&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Fixes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed the behavior of &lt;code&gt;:include_blank&lt;/code&gt; and &lt;code&gt;:prompt&lt;/code&gt; options to be inline with Rails’&lt;/li&gt;
		&lt;li&gt;Fixed that &lt;code&gt;:input_html =&amp;gt; { :multiple =&amp;gt; true }&lt;/code&gt; did not force a single choice select into a multi choice&lt;/li&gt;
		&lt;li&gt;Fixed date, time and datetime legend labels to correspond to the first visible input, rather than the first input (which may be hidden)&lt;/li&gt;
		&lt;li&gt;Fixed that DateInput should treat fragments excluded from &lt;code&gt;:order&lt;/code&gt; option as discarded&lt;/li&gt;
		&lt;li&gt;Fixed that the &lt;code&gt;:wrapper_html&lt;/code&gt; options could not be reused in the view (like in a &lt;code&gt;with_options&lt;/code&gt; block) because they were modified by Formtastic&lt;/li&gt;
		&lt;li&gt;Fixed numerous Mongoid and MongoMapper compatibility issues&lt;/li&gt;
		&lt;li&gt;Fixed that we should be calculating the length of integer columns as bytes&lt;/li&gt;
		&lt;li&gt;Fixed many inputs (date, datetime, time, checkboxes, select &amp; boolean) that did not correctly use the &lt;code&gt;:index&lt;/code&gt; option in &lt;code&gt;fields_for&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Fixed Haml and Slim template indentation&lt;/li&gt;
		&lt;li&gt;Fixed invalid html output for nested inputs with multiple siblings&lt;/li&gt;
		&lt;li&gt;Fixed i18n keys with nested objects&lt;/li&gt;
		&lt;li&gt;Many documentation fixes and improvements&lt;/li&gt;
		&lt;li&gt;A few performance improvements&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;I’ll be writing more on the new Actions DSL in the future, but it closely follows the patterns of the Inputs DSL, allowing for your own custom actions (pretty buttons, different markup, different labelling, whatever you like). For the moment, there’s some basic documentation of &lt;a href="http://rubydoc.info/github/justinfrench/formtastic/master/Formtastic/Helpers/ActionsHelper"&gt;ActionsHelper&lt;/a&gt;, which should feel pretty familiar.&lt;/p&gt;
	&lt;p&gt;Please test this release, please &lt;a href="https://github.com/justinfrench/formtastic/issues"&gt;add issues to Github&lt;/a&gt; for any bugs WTF moments you have, and spread the word!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/XcMEUNA9Inc" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-210beta1-released</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-10-17T21:40:00Z</published>
		<updated>2011-10-17T21:43:55Z</updated>
		<title>Sharing Todo Lists with iOS 5's Reminders app</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/IRP0qEfbuU4/sharing-todo-lists-with-ios-5s-reminders-app" />
		<id>tag:justinfrench.com,2011-10-17:083bed6ad50451eb341a307b6c00ee12/7fee04d00b3b3297c3db3d0ad19059f1</id>
		<category term="Apple" />
		
		<content type="html">
	&lt;p&gt;Last night I figured out that it’s possible to share your reminder lists with other iCloud users, like a &lt;em&gt;Groceries&lt;/em&gt; list shared with my wife Kate, which we’re trying out right now.&lt;/p&gt;
	&lt;p&gt;The new Reminders app in iOS 5 leaves a lot of room for improvement, and this is a big one — there’s no indication anywhere in the iOS interface that you can share these lists, but you can!&lt;/p&gt;
	&lt;p&gt;Under the hood, the reminder lists are stored on iCloud as part of iCal’s data. On a whim, I logged into iCloud’s web interface, went to my calendar, found the Groceries reminder list, and shared it with Kate’s iCloud email address, just like we already do with some shared calendars.&lt;/p&gt;
	&lt;p&gt;&lt;img src="/images/12.png" title="Screen shot showing the UI for sharing reminder lists" alt="Screen shot showing the UI for sharing reminder lists" /&gt;&lt;/p&gt;
	&lt;p&gt;So far, it works great!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/IRP0qEfbuU4" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;The new Reminders app in iOS 5 leaves a lot of room for improvement, and this is a big one — there’s no indication anywhere in the iOS interface that you can share these lists, but you can!&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/sharing-todo-lists-with-ios-5s-reminders-app</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-10-11T22:32:00Z</published>
		<updated>2011-10-11T22:32:58Z</updated>
		<title>Talking to Your Customers</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/YfiC7mcmk84/talking-to-your-customers" />
		<id>tag:justinfrench.com,2011-10-11:083bed6ad50451eb341a307b6c00ee12/d770aa58f441e38c4f885f1ac070ab53</id>
		<category term="Design" />
		<category term="Product" />
		<content type="html">
	&lt;p&gt;Talking to your customers is crucial to the success of your product. Call it Customer Development, User Centered Design or Market Research, just make sure you’re doing it.&lt;/p&gt;
	&lt;h3&gt;It’s not hard to do&lt;/h3&gt;
	&lt;p&gt;Find a customer, or a potential customer, and start talking. If you’re nervous or lack the confidence to do this one-on-one (you’re absolutely not alone), grab your product manager,  designer, tech lead, CEO or anyone else in your team and do it together. Reduce the formality and ceremony over a coffee or a beer. Start over email, on the phone. Invite your most trusted customers to talk among themselves in a private email group.&lt;/p&gt;
	&lt;p&gt;Starting is far more important than how you start. I don’t need to prepare too much either – it’s pretty easy to get people to talk about themselves and their work.&lt;/p&gt;
	&lt;h3&gt;What not to do&lt;/h3&gt;
	&lt;p&gt;Don’t talk about features. Asking them what features they want (or letting them push the conversation that way) is a complete waste of time. There’s two predictable outcomes, both of which should be considered negatives:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;You walk away with a checklist of stuff you need before they’ll buy&lt;/li&gt;
		&lt;li&gt;The customer walks away with a list of reasons not to buy your product&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;What to do instead&lt;/h3&gt;
	&lt;p&gt;Ask them about their job, tasks, workflow, process and constraints. Ask them how they get stuff done. Ask them what they do, not what they need. The outcomes from this are far more positive:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;You know if this is the sort of customer you want to help.&lt;/li&gt;
		&lt;li&gt;You build empathy for this customer.&lt;/li&gt;
		&lt;li&gt;You have a much deeper insight into the customer’s true needs.&lt;/li&gt;
		&lt;li&gt;You have real scenarios to draw upon and real problems to solve.&lt;/li&gt;
		&lt;li&gt;The customer builds a relationship with you and your product far beyond the software.&lt;/li&gt;
		&lt;li&gt;The customer talks directly with someone who can shape the product.&lt;/li&gt;
		&lt;li&gt;The customer invests time in your product, and has an interest in it’s success.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;If you must talk about features, always dig deeper. Shift the conversation away from the implementation to the reasons behind it. Instead of talking about that epic reporting widget they need, talk about &lt;em&gt;why&lt;/em&gt; they need it, and how that helps them get stuff done.&lt;/p&gt;
	&lt;p&gt;Push them to articulate the problem, rather than prescribe the solution. It’s your job as a product designer to aggregate and consider the problems from many customers and design your own solution. Yes, it’s your product, you design it.&lt;/p&gt;
	&lt;p&gt;After listening to the problem, you may already have features that can help. This is awesome! You’ve just avoided a conversation about “missing features” and showed them how your product can help them right now.&lt;/p&gt;
	&lt;p&gt;If you find a real gap in your product, don’t instantly promise a feature to fill it. Instead, promise to spend time thinking about it. Ask them if they’d mind a follow-up conversation (if this is important to them, they’ll be excited to help).&lt;/p&gt;
	&lt;p&gt;“What they do” is far more valuable and interesting than “what they want”.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/YfiC7mcmk84" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Talking to your customers is crucial to the success of your product. Call it Customer Development, User Centered Design or Market Research. Make sure you don’t fall into the feature trap!&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/talking-to-your-customers</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-09-26T05:33:00Z</published>
		<updated>2011-09-26T22:52:41Z</updated>
		<title>Formtastic 2.0</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/8AC8Ose9OhY/formtastic-20" />
		<id>tag:justinfrench.com,2011-09-26:083bed6ad50451eb341a307b6c00ee12/92cce4d690140f732104d61746f60dec</id>
		<category term="Formtastic" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt; 2.0 finally shipped over the weekend.&lt;/p&gt;
	&lt;p&gt;It’s been an epic, epic ride with contributions from 43 awesome coders. Many many thanks to Aditya Sanghi, Balazs Nagy, beawesomeinstead, Bruce Williams, Chad Ostrowski, Christoph Thiel, Corin Langosch, Corin Langosch, Daiki Ueno, DeLynn Berry, Edgars Beigarts, eugen neagoe, Gabriel Sobrinho, Ijonas Kisselbach, iscra, Jakub Okoński, Jan Schwenzien, Jason King, Joe Winter, Josh Kalderimis, Juan M. Cuello, Justin French, Kent Fenwick, Kjel Delaey, Kjel Delaey, Konstantin Shabanov, Kouhei Sutou, Lars O. Overskeid, Matt Huggins, Matt Vague, Mattias Pfeiffer, Mikael Henriksson, nashby, Nathan S, Petteri Räty, Pirogov Evgenij, Robin Stocker, Ryan Garver, smix, Thomas Walpole, Timothy Klim, Victor Stan and Wojciech Wnętrzak.&lt;/p&gt;
	&lt;p&gt;The &lt;a href="https://github.com/justinfrench/formtastic/blob/2.0.0/CHANGELOG"&gt;changelog&lt;/a&gt; has the full details blow-by-blow, but for those with a short attention span, here’s the big tickets:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Dropped Rails 2 support&lt;/li&gt;
		&lt;li&gt;Added Rails 3.1 support, including the asset pipeline&lt;/li&gt;
		&lt;li&gt;Massive internal refactor, allowing for much simpler &lt;a href="http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs"&gt;custom inputs&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Added many new classes to DOM elements to enable more efficient and descriptive CSS&lt;/li&gt;
		&lt;li&gt;Massive refactor and simplification of the stylesheets&lt;/li&gt;
		&lt;li&gt;Massive &lt;a href="http://rdoc.info/github/justinfrench/formtastic"&gt;documentation effort&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Added support for HTML5 &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;step&lt;/code&gt;, &lt;code&gt;placeholder&lt;/code&gt; and &lt;code&gt;autofocus&lt;/code&gt; attributes&lt;/li&gt;
		&lt;li&gt;Improved support for Mongoid and MongoMapper documents&lt;/li&gt;
		&lt;li&gt;Changed nested inputs() blocks to be automatically wrapped in an &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag to preserve HTML validity&lt;/li&gt;
		&lt;li&gt;Changed quick forms to skip polymorphic associations (they didn’t work)&lt;/li&gt;
		&lt;li&gt;Changed short hand forms to raise an error when trying to render an input for a polymorphic association (it didn’t work, need a collection)&lt;/li&gt;
		&lt;li&gt;Changed input() to raise an error when a :collection is not provided for a polymorphic association (we can’t guess which class to use)&lt;/li&gt;
		&lt;li&gt;Changed :label_method option to :member_label, :value_method option to :member_value, :grouped_label_method to :grouped_label (with backwards compat and deprecation warnings)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Enjoy!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/8AC8Ose9OhY" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-20</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-09-13T01:11:31Z</published>
		<updated>2011-09-13T01:11:31Z</updated>
		<title>Head, Heart &amp; Hand</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/yZJM5P2-kPk/head-heart-hand" />
		<id>tag:justinfrench.com,2011-09-12:083bed6ad50451eb341a307b6c00ee12/e8bec56370873874fdf90e900e2c5a18</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;I love &lt;a href="http://www.ted.com/talks"&gt;TED talks&lt;/a&gt;. Randomly selected for my commute home this evening was &lt;a href="http://www.ted.com/talks/lang/eng/shea_hembrey_how_i_became_100_artists.html"&gt;How I became 100 artists&lt;/a&gt; by &lt;a href="http://www.sheahembrey.com/"&gt;Shea Hembrey&lt;/a&gt;. What I love about these talks is how often I can apply these ideas and experiences to my own world.&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;So amongst all the criteria I have, there’s two main things. One of them, I call my Mimaw’s Test. And what that is is I imagine explaining a work of art to my grandmother in five minutes. And if I can’t explain it in five minutes, then it’s too obtuse or esoteric and it hasn’t been refined enough yet. It needs to worked on until it can speak fluently. And then my other second set of [...] criteria would be the three H’s, which is head, heart and hand. And great art would have head — it would have interesting intellectual ideas and concepts. It would have heart in that it would have passion and heart and soul. And it would have hand in that it would be greatly crafted.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;This goes far beyond curating art, right? He could just as easily been describing the type of projects we love to work on, the companies we respect and the products that delight us.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/yZJM5P2-kPk" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/head-heart-hand</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-09-01T13:56:00Z</published>
		<updated>2011-09-01T14:14:47Z</updated>
		<title>Announcing Formtastic 2.0.0.rc5</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/0gjlefvGeFA/announcing-formtastic-200rc5" />
		<id>tag:justinfrench.com,2011-09-01:083bed6ad50451eb341a307b6c00ee12/0d33d6459f08556aaabfa314e21dc324</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;It’s been a long but enjoyable path from &lt;a href="http://justinfrench.com//notebook/announcing-formtastic-200rc1"&gt;the first release candidate&lt;/a&gt;, but I think we’re finally here! Pending any major new issues found, this will be the final release candidate and Formtastic 2 will ship in the next week.&lt;/p&gt;
	&lt;p&gt;Here’s an extract from the &lt;a href="https://github.com/justinfrench/formtastic/blob/master/CHANGELOG"&gt;CHANGELOG&lt;/a&gt; since 2.0.0.rc1:&lt;/p&gt;
	&lt;h3&gt;2.0.0.rc5&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Changed &lt;code&gt;perform_browser_validations&lt;/code&gt; and &lt;code&gt;use_required_attribute&lt;/code&gt; configuration defaults from true to false for a better out-of-the-box experience and upgrade path&lt;/li&gt;
		&lt;li&gt;Fixed that the &lt;code&gt;novalidate&lt;/code&gt; attribute was being applied to the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag when it shouldn’t have been (and vice-versa)&lt;/li&gt;
		&lt;li&gt;Fixed &lt;code&gt;undefined method `last' for #&amp;lt;Classname&amp;gt;&lt;/code&gt; with a &lt;code&gt;:collection&lt;/code&gt; containing an array of arrays&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;2.0.0.rc4&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed that &lt;code&gt;TimeInput&lt;/code&gt; was not rendering hidden y/m/d inputs by default.&lt;/li&gt;
		&lt;li&gt;Fixed test suite under Rails 3.1.0.rc5&lt;/li&gt;
		&lt;li&gt;Fixed false and blank fragment labels on date/time inputs producing unsafe HTML.&lt;/li&gt;
		&lt;li&gt;Fixed that inputs were ‘required’ without considering &lt;code&gt;:on =&amp;gt; :create&lt;/code&gt; validations&lt;/li&gt;
		&lt;li&gt;Fixed that collections of strings in &lt;code&gt;CheckBoxesInput&lt;/code&gt; were not being correctly checked be checked if they match the model&lt;/li&gt;
		&lt;li&gt;Fixed that the required attribute was added to the choices in a &lt;code&gt;:radio&lt;/code&gt; or &lt;code&gt;:check_boxes&lt;/code&gt; input, instead of just the parent input wrapper&lt;/li&gt;
		&lt;li&gt;Fixed &lt;code&gt;semantic_fields_for&lt;/code&gt; when used with a hash-like model&lt;/li&gt;
		&lt;li&gt;Fixed that models without defined validations (even if &lt;code&gt;validators_on&lt;/code&gt; exists) should not be considered required&lt;/li&gt;
		&lt;li&gt;Fixed &lt;code&gt;min&lt;/code&gt;/@max@ attributes when the validation uses a &lt;code&gt;Proc&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Fixed that inputs should not be considered required if &lt;code&gt;:allow_blank =&amp;gt; true&lt;/code&gt; is set on &lt;code&gt;validates_inclusion_of&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Fixed that inputs should not be considered required if either &lt;code&gt;:allow_blank =&amp;gt; true&lt;/code&gt;, &lt;code&gt;:minimum&lt;/code&gt; is &lt;code&gt;&amp;gt; 0&lt;/code&gt;, or &lt;code&gt;:within&lt;/code&gt;’s least value is &lt;code&gt;&amp;gt; 0&lt;/code&gt; is set on &lt;code&gt;validates_length_of&lt;/code&gt; &lt;/li&gt;
		&lt;li&gt;Fixed a typo in the config template&lt;/li&gt;
		&lt;li&gt;Fixed &lt;code&gt;semantic_fields_for&lt;/code&gt; to work with Rails 3 and 3.1’s method sigs, many thanks to the simple_form guys for figuring this out&lt;/li&gt;
		&lt;li&gt;Changed HTML5 &lt;code&gt;step&lt;/code&gt; attribute to default to &lt;code&gt;any&lt;/code&gt; instead of &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Added CarrierWave support for to file input detection&lt;/li&gt;
		&lt;li&gt;Added a configuration &lt;code&gt;perform_browser_validations&lt;/code&gt; to opt out of HTML5 browser validations.&lt;/li&gt;
		&lt;li&gt;Added more support for mongo documents, including MongoMapper-specific reflection capability&lt;/li&gt;
		&lt;li&gt;Added IE specific stylesheets &amp; moved those styles out of main stylesheet, include them yourself if needed&lt;/li&gt;
		&lt;li&gt;Added a new configuration to opt out of HTML5 required attribute&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;2.0.0.rc3&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed that &lt;code&gt;.label&lt;/code&gt; class was incorrectly applied to &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; tags inside a &lt;code&gt;.choice&lt;/code&gt; on radio and checkbox inputs&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;2.0.0.rc2&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed install instructions in README to reflect 2.0.0.rc1&lt;/li&gt;
		&lt;li&gt;Fixed that the checkbox was mistakenly placed after the label text in &lt;code&gt;BooleanInput&lt;/code&gt;, not before it as per 1.x&lt;/li&gt;
		&lt;li&gt;Fixed that select inputs had two &lt;code&gt;blank&lt;/code&gt; options at the top in some cases&lt;/li&gt;
		&lt;li&gt;Added documentation for &lt;code&gt;Timeish&lt;/code&gt; inputs (date, datetime, time)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;With Rails 3.1 freshly released, now is a great time to help ensure this is a solid release.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/0gjlefvGeFA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/announcing-formtastic-200rc5</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-06-09T11:22:00Z</published>
		<updated>2011-06-19T10:24:20Z</updated>
		<title>Announcing Formtastic 2.0.0.rc1</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/o-HEYz6YFd4/announcing-formtastic-200rc1" />
		<id>tag:justinfrench.com,2011-06-09:083bed6ad50451eb341a307b6c00ee12/b82eed336b6f72ee08fc765d2b5c4dc5</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;I’ve just pushed &lt;a href="http://rubygems.org/gems/formtastic"&gt;Formtastic 2.0.0.rc1 up to Ruby Gems&lt;/a&gt; including a massive 493 commits made by 26 contributors. I’ll start with the highlights, then work down to the details.&lt;/p&gt;
	&lt;h3&gt;A massive refactor&lt;/h3&gt;
	&lt;p&gt;My major goal was a long overdue internal refactor of the code to suit it’s current requirements. We’ve come a long way from a couple of helper methods.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;drop Rails 2.x support and the many work-arounds we had in place to support it&lt;/li&gt;
		&lt;li&gt;pay down massive debt in the code base&lt;/li&gt;
		&lt;li&gt;make the code more approachable for contributors&lt;/li&gt;
		&lt;li&gt;make the code easier to document&lt;/li&gt;
		&lt;li&gt;make the code easier to override and customise&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;We’ve definitely acheived this (I started to recieve pull requests rather than bug reports almost imediately after I merged in my work), and I’m now proud of most corners of the code base. The giant monster formtastic.rb has been broken down into around 40 classes and modules with much smaller methods. It’s generally Good Ruby™, with room for improvement of course.&lt;/p&gt;
	&lt;h3&gt;A massive documentation effort&lt;/h3&gt;
	&lt;p&gt;By breaking up the code, it became way easier to document, so I poured more hours than I care to admit into Yard documentation which you can see on &lt;a href="http://rdoc.info/github/justinfrench/formtastic"&gt;rdoc.info/github/justinfrench/formtastic&lt;/a&gt;. Have a read, send pull requests, make it ever better!&lt;/p&gt;
	&lt;h3&gt;Custom inputs &lt;/h3&gt;
	&lt;p&gt;Another benefit of breaking up the code into smaller classes, modules and methods is that it’s now ridiculosly easy to modify the inputs to suit your needs, or make your own custom inouts with plain old Ruby. For more detail, see &lt;a href="http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs"&gt;Formtastic 2 Preview: Custom Inputs&lt;/a&gt; from back in April.&lt;/p&gt;
	&lt;h3&gt;Rails 3.1 support, including the asset pipeline&lt;/h3&gt;
	&lt;p&gt;Rails threw us a bit of a curve ball with Rails 3.1 mid-refactor, but the transition was pretty smooth. There’s one known issue with &lt;code&gt;semantic_form_for&lt;/code&gt; (see below for a longer description and a work-around if it affects you) which I’m still looking into, with a second RC to follow as soon as possible.&lt;/p&gt;
	&lt;h3&gt;Cleaner, leaner, descriptive CSS&lt;/h3&gt;
	&lt;p&gt;A lot has changed since I cobbled together the first version of &lt;code&gt;formtastic.css&lt;/code&gt; as a proof of concept. I no longer believe in ultra specific selectors, I prefer styling by class names instead of elements, and I like finding ways for my CSS to be more expressive and composable. The result for Formtastic is that the CSS is now about 40% of it’s original size, much easier to work with and hooks into a bunch of new classes I’ve added to the generated HTML. You also won’t find yourself fighting a specificity war to override something.&lt;/p&gt;
	&lt;h3&gt;Other additions&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Added support for HTML5 &lt;code&gt;required&lt;/code&gt; attribute on &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; and &lt;code&gt;≤textarea&amp;gt;&lt;/code&gt; tags&lt;/li&gt;
		&lt;li&gt;Added support for HTML5 &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt; and &lt;code&gt;step&lt;/code&gt; attributes on &lt;code&gt;NumericInput&lt;/code&gt; (aka &lt;code&gt;NumberInput&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;Added support for HTML5 &lt;code&gt;placeholder&lt;/code&gt; attributes on “stringish” inputs (string, email, phone, url, search, number, password)&lt;/li&gt;
		&lt;li&gt;Added support for HTML5 &lt;code&gt;autofocus&lt;/code&gt; attribute&lt;/li&gt;
		&lt;li&gt;Added support for a &lt;code&gt;Method&lt;/code&gt; object in &lt;code&gt;:member_label&lt;/code&gt;/@:member_value@ (aka &lt;code&gt;:label_method&lt;/code&gt;/@:value_method@)&lt;/li&gt;
		&lt;li&gt;Added improved support for Mongoid documents&lt;/li&gt;
		&lt;li&gt;Added many new HTML classes to DOM elements to enable more efficient and descriptive CSS&lt;/li&gt;
		&lt;li&gt;Added targetted IE6 and IE7 stylesheets for specific fixes if needed (uncomplicates formtastic.css)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Other changes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Changed &lt;code&gt;Formtastic::SemanticFormHelper&lt;/code&gt; to &lt;code&gt;Formtastic::Helpers::FormHelper&lt;/code&gt; (&lt;code&gt;SemanticFormHelper&lt;/code&gt; still exists as a module which includes the new module, need to handle deprecation notices somehow)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;Formtastic::SemanticFormBuilder&lt;/code&gt; to &lt;code&gt;Formtastic::FormBuilder&lt;/code&gt; (&lt;code&gt;SemanticFormBuilder&lt;/code&gt; still exists as a subclass, need to handle deprecation notices somehow)&lt;/li&gt;
		&lt;li&gt;Changed the HTML &lt;code&gt;id&lt;/code&gt; attribute used for hidden inputs to be consistent with all other inputs&lt;/li&gt;
		&lt;li&gt;Changed form generator include the wrapping &lt;code&gt;semantic_form_for&lt;/code&gt; block&lt;/li&gt;
		&lt;li&gt;Changed nested &lt;code&gt;inputs()&lt;/code&gt; blocks to be automatically wrapped in an &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag to preserve HTML validity without extra mark-up in the form DSL&lt;/li&gt;
		&lt;li&gt;Changed quick forms (&lt;code&gt;f.inputs&lt;/code&gt; without args) to skip over polymorphic associations (they didn’t work)&lt;/li&gt;
		&lt;li&gt;Changed short hand forms (&lt;code&gt;f.inputs(:att, :att, :att)&lt;/code&gt;) to raise an error when trying to render an input for a polymorphic association (it didn’t work, need a &lt;code&gt;:collection&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;input()&lt;/code&gt; to raise an error when a &lt;code&gt;:collection&lt;/code&gt; is not provided for a polymorphic association (we can’t guess which class to use)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:label_method&lt;/code&gt; option to &lt;code&gt;:member_label&lt;/code&gt; (with backwards compatibility and deprecation warnings)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:value_method&lt;/code&gt; option to &lt;code&gt;:member_value&lt;/code&gt; (with backwards compatibility and deprecation warnings)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:grouped_label_method&lt;/code&gt; option to &lt;code&gt;:grouped_label&lt;/code&gt; (with backwards compatibility and deprecation warnings)&lt;/li&gt;
		&lt;li&gt;Changed Rails dependency to ~3.1 allow Rails 3.1, 3.2, etc&lt;/li&gt;
		&lt;li&gt;Changed install generator to copy a form partial into &lt;code&gt;lib/templates/&lt;/code&gt;, overriding the standard form scaffold like Simple Form does (removed &lt;code&gt;formtastic:form&lt;/code&gt; generator)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;NumericInput&lt;/code&gt; to &lt;code&gt;NumberInput&lt;/code&gt; (&lt;code&gt;:as =&amp;gt; :number&lt;/code&gt;) to align with the new HTML5 number input type&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Other fixes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed visual/spacing consistency on checkboxes and radio buttons&lt;/li&gt;
		&lt;li&gt;Fixed CSS compatibility and visual consistency in IE7, fixed/added support for IE6 by removing &lt;code&gt;&amp;gt;&lt;/code&gt; selectors&lt;/li&gt;
		&lt;li&gt;Fixed that overly specific CSS rules weren’t applied to nested form elements properly&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Stuff we burned&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Removed &lt;code&gt;formtastic_stylesheet_link_tag&lt;/code&gt; (use &lt;code&gt;stylesheet_link_tag("formtastic")&lt;/code&gt;, or use asset pipeline)&lt;/li&gt;
		&lt;li&gt;Removed the &lt;code&gt;inline_order&lt;/code&gt; configuration option (use custom inputs or redefine the &lt;code&gt;input_wrapping&lt;/code&gt; method instead)&lt;/li&gt;
		&lt;li&gt;Removed our custom implementation of &lt;code&gt;f.label()&lt;/code&gt; helper&lt;/li&gt;
		&lt;li&gt;Removed &lt;code&gt;semantic_remote_form_for&lt;/code&gt; etc, the remote form helpers are gone in Rails 3&lt;/li&gt;
		&lt;li&gt;Removed some overly eager CSS resets on form elements that made Opera and Firefox inputs look pretty ugly&lt;/li&gt;
		&lt;li&gt;Removed specificity and duplication in CSS&lt;/li&gt;
		&lt;li&gt;Removed &lt;code&gt;formtastic:form&lt;/code&gt; generator (we override scaffolding generator form template, see above)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Known issues&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Rails 3.1 introduced some incompatibilities on the &lt;code&gt;fields_for&lt;/code&gt; API (which is wrapped by &lt;code&gt;semantic_fields_for&lt;/code&gt;) see &lt;a href="https://github.com/rails/rails/issues/1045"&gt;this Rails issue&lt;/a&gt; and &lt;a href="https://github.com/justinfrench/formtastic/issues/568"&gt;this Formtastic issue&lt;/a&gt; for the work-around&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;SemanticFormBuilder&lt;/code&gt; and &lt;code&gt;SemanticFormHelper&lt;/code&gt; have been renamed, but not much has been done about deprecation warnings to get folks migrating&lt;/li&gt;
		&lt;li&gt;Folks who subclassed &lt;code&gt;SemanticFormBuilder&lt;/code&gt; and created their own custom inputs as methods will be in for some pain&lt;/li&gt;
		&lt;li&gt;No documentation on upgrading yet (help!)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;A call to action&lt;/h3&gt;
	&lt;p&gt;Create a branch in your app today. Bundle in 2.0.0.rc1 and spin up your app, have a click around, run your test suite, pay attention to any deprecations and &lt;a href="http://github.com/justinfrench/formtastic/issues/new"&gt;create issues on Github&lt;/a&gt; for anything broken, surprising, unexpected or frustrating. Tweet &lt;a href="http://twitter.com/justinfrench"&gt;@formtastic&lt;/a&gt; if you’re happy!&lt;/p&gt;
	&lt;p&gt;If you’re keen, keep an eye out for issues and send pull requests.&lt;/p&gt;
	&lt;p&gt;Rails 3.1 could be final two weeks from now, and I’d love to ship a solid release on the same day.&lt;/p&gt;
	&lt;h3&gt;Updates…&lt;/h3&gt;
	&lt;h4&gt;2.0.0.rc2&lt;/h4&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed install instructions in readme to reflect 2.0.0.rc1&lt;/li&gt;
		&lt;li&gt;Fixed that the checkbox was mistakenly placed after the label text in BooleanInput, not before it as per 1.x (#591)&lt;/li&gt;
		&lt;li&gt;Fixed that select inputs had two “blank” options at the top in some cases (#590)&lt;/li&gt;
		&lt;li&gt;Added documentation for Timeish inputs (date, datetime, time) (#589)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h4&gt;2.0.0.rc3&lt;/h4&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed that .label class was incorrectly applied to &lt;label&gt; tags inside a .choice on radio and checkbox inputs (#599)&lt;/li&gt;
	&lt;/ul&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/o-HEYz6YFd4" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/announcing-formtastic-200rc1</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-05-31T22:07:00Z</published>
		<updated>2011-06-01T05:22:01Z</updated>
		<title>Formtastic 1.2.4</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/4UjNl3wJYb0/formtastic-124" />
		<id>tag:justinfrench.com,2011-05-31:083bed6ad50451eb341a307b6c00ee12/df5212ff94e26bb4777373fd4c781f48</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;This isn’t the big 2.0 refactor release, but I’ve just pushed Formtastic 1.2.4 up to RubyGems. It contains a bunch of small bug fixes and improvements over the past few months.&lt;/p&gt;
	&lt;p&gt;If you’ve been using 1.2.4.beta2, this release is identical. If you’ve been rolling with 1.2.3, there’s no changes that should prevent you from upgrading.&lt;/p&gt;
	&lt;p&gt;This release should be compatible with Rails 2 and Rails 3, although we’re focusing most of our Rails 3.1 work in the master branch for Formtastic 2.&lt;/p&gt;
	&lt;p&gt;Speaking of Formtastic 2, we’re aiming to ship a release candidate &lt;strong&gt;this week&lt;/strong&gt;! Bundle in from master direct with the &lt;code&gt;:git&lt;/code&gt; option if you want to try it out before then.&lt;/p&gt;
	&lt;p&gt;Changelog from 1.2.3–1.2.4:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Changed &lt;code&gt;:boolean&lt;/code&gt; inputs to use Rails’ &lt;code&gt;check_box_checked?&lt;/code&gt; instead of our own logic (addresses many bugs)&lt;/li&gt;
		&lt;li&gt;Fixed &lt;code&gt;:boolean&lt;/code&gt; inputs to disable the included hidden input when disabling the visible checkbox&lt;/li&gt;
		&lt;li&gt;Fixed that Formtastic was making changes to the options hash directly instead of on a duplicate, causing problems for those trying to reuse options on multiple inputs in the view &lt;/li&gt;
		&lt;li&gt;Fixed that tiny scroll bars were appearing on legends in date/time/radio/cbheckboxes fielsets&lt;/li&gt;
		&lt;li&gt;Fixed an issue when Formtastic fails to determine if a checkbox is checked with custom checked and unchecked values&lt;/li&gt;
		&lt;li&gt;Fixed that the hidden input rendered with a boolean checkbox did nt use the custom &lt;code&gt;:name&lt;/code&gt; from &lt;code&gt;:input_html&lt;/code&gt; options hash if provided&lt;/li&gt;
		&lt;li&gt;Fixed CSS/Firefox issue where Firefox 4 gave focus to the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; wrapper, requiring the user to press tab twice to jump between inputs&lt;/li&gt;
		&lt;li&gt;Improved compatibility with Mongoid Documents&lt;/li&gt;
		&lt;li&gt;Updated i18n dependency to ~&gt; 0.4&lt;/li&gt;
	&lt;/ul&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/4UjNl3wJYb0" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-124</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-05-26T23:17:00Z</published>
		<updated>2011-05-27T00:19:14Z</updated>
		<title>Announcing Nestive – Better Nested Layouts for Rails</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/TeI6JaWQ1DA/announcing-nestive--better-nested-layouts-for-rails" />
		<id>tag:justinfrench.com,2011-05-26:083bed6ad50451eb341a307b6c00ee12/9b99b046eb5ffd22127c4637a0cc61c6</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;Last night at the monthly Melbourne Ruby meet-up I gave a quick presentation on Nested Layouts (aka Inheritable Layouts, Extensible Layouts, etc). I stepped through a bunch of the options, plugins and strategies available today, then finally showed off a new plugin I’ve been working on called &lt;a href="https://github.com/justinfrench/nestive"&gt;Nestive&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;Nestive is a partial answer to two things that have been really bugging me:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;The current Rails best practice for nested layouts, &lt;a href="http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts"&gt;as described in the Rails Guides&lt;/a&gt; is utterly flawed for anything except the most basic examples&lt;/li&gt;
		&lt;li&gt;I’ve had serious framework envy ever since Jeff Croft’s &lt;a href="http://jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/"&gt;Django Templates: The Power of Inheritance&lt;/a&gt; was published back in 2006&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;We’re going to have trouble replicating Django’s DSL in ERB/ActionView (with keywords like `block` and `super`), but I think I’ve come up with a pretty tidy DSL involving just four simple methods.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;code&gt;area&lt;/code&gt; (declare an area in the layout, similar to &lt;code&gt;yield&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;extend&lt;/code&gt; (tell your layout or view to extend/inherit the another layout)&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;append&lt;/code&gt; (similar to &lt;code&gt;content_for&lt;/code&gt;, add stuff onto an area)&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;prepend&lt;/code&gt; (the opposite of &lt;code&gt;append&lt;/code&gt;, duh)&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;replace&lt;/code&gt; (set completely new content for an area)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;You can read about all this in much more detail with a bunch of examples in the &lt;a href="https://github.com/justinfrench/nestive/blob/master/README.md"&gt;Nestive README on GitHub&lt;/a&gt;, or &lt;a href="http://dl.dropbox.com/u/1044682/Presentatons/justin-french-nestive-roro-may-2011.pdf"&gt;download the slides from my presentation&lt;/a&gt; (sorry there’s no presenter notes).&lt;/p&gt;
	&lt;p&gt;Right now, I’d love help from the community validating the entire concept. Try it out in a small project or a small part of a big project (it doesn’t mess with any of the Rails internals), try it with Haml, report issues, give me feedback on the DSL, etc.&lt;/p&gt;
	&lt;p&gt;I’m also wondering if it could be wired into Sinatra and other Ruby frameworks, and how it will impact things like Rails 3.1’s content streaming.&lt;/p&gt;
	&lt;p&gt;Fork it, patch it, break it, create issues, help me write some tests!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/TeI6JaWQ1DA" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Last night at the monthly Melbourne Ruby meet-up I gave a quick presentation on Nested Layouts and announced a new plugin for Rails called Nestive.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/announcing-nestive--better-nested-layouts-for-rails</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-04-06T21:28:05Z</published>
		<updated>2011-04-06T21:28:05Z</updated>
		<title>Formtastic 2 Preview: Custom Inputs</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/qFpNIVfugic/formtastic-2-preview-custom-inputs" />
		<id>tag:justinfrench.com,2011-04-06:083bed6ad50451eb341a307b6c00ee12/7a1ecc07d7c3787585a580088aa4de9d</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;I’ve been pouring more hours than I care to admit into a massive refactor of Formtastic. I’m really happy with where it’s headed, so it’s time to share some of the goodies!&lt;/p&gt;
	&lt;p&gt;Custom inputs (the ability to define your own input type) has been on my list since day one, and the refactor has made it &lt;em&gt;really&lt;/em&gt; easy. Each input is now handled by it’s own class, which obviously lets us take advantage of things like class inheritance and composition with modules.&lt;/p&gt;
	&lt;p&gt;Under the hood, when you render an input with something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;lt;%= f.input :title, :as =&amp;gt; :number %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;We’re creating a new instance of the &lt;code&gt;Formtastic::Inputs::NumberInput&lt;/code&gt; class and calling &lt;code&gt;#to_html&lt;/code&gt; on it. That class looks something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  class NumberInput 
    include Base
    include Base::Stringish
    def to_html
      input_wrapping do
        label_html &amp;lt;&amp;lt;
        builder.number_field(method, input_html_options)
      end
    end
    def input_html_options
      {
        :min =&amp;gt; validation_min,
        :max =&amp;gt; validation_max,
        :step =&amp;gt; validation_integer_only? ? 1 : nil 
      }.merge(super)
    end
  end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Most of the heavy lifting is done in the included modules. This class is only concerned with the things that are &lt;strong&gt;different&lt;/strong&gt; about a number input compared to other “stringish” inputs like &lt;code&gt;SearchInput&lt;/code&gt;, &lt;code&gt;PhoneInput&lt;/code&gt;, &lt;code&gt;EmailInput&lt;/code&gt; and of course &lt;code&gt;StringInput&lt;/code&gt;.&lt;/p&gt;
	&lt;p&gt;In this case, we’ve added default &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt; and &lt;code&gt;step&lt;/code&gt; attributes for the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag, and implemented &lt;code&gt;#to_html&lt;/code&gt;, which calls Rails’ &lt;code&gt;number_field&lt;/code&gt; helper. It could (and probably will) be abstracted even further before I’m done, but for now it’s all about the vibe of the thing.&lt;/p&gt;
	&lt;p&gt;Here’s the cool bit. Before instantiating &lt;code&gt;Formtastic::Inputs::NumberInput&lt;/code&gt;, we try to instantiate a top-level class &lt;code&gt;NumberInput&lt;/code&gt;. This means you can create a &lt;code&gt;NumberInput&lt;/code&gt; class in &lt;code&gt;app/inputs/number_input.rb&lt;/code&gt;, inherit from &lt;code&gt;Formtastic::Inputs::NumberInput&lt;/code&gt; and make any modifications you want to the class. Under the hood, there’s about 55 methods available on &lt;code&gt;NumberInput&lt;/code&gt; which you can override, but you could ultimately do anything you want by overriding &lt;code&gt;#to_html&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  class NumberInput &amp;lt; Formtastic::Inputs::NumberInput
    def to_html
      "Return whatever HTML string you want, however you want."
    end
  end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;A more likely and less dramatic scenario might be to add a special class to the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; wrapper tag, ditch those new HTML5 &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max &amp; @step&lt;/code&gt; attributes and use a &lt;code&gt;text&lt;/code&gt; input instead of the HTML5 &lt;code&gt;number&lt;/code&gt; input. Easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  class NumberInput &amp;lt; Formtastic::Inputs::NumberInput
    def to_html
      input_wrapping do
        label_html &amp;lt;&amp;lt;
        builder.text_field(method, input_html_options)
      end
    end
    def input_html_options
      super.reject { |k, v| [:min, :max, :step].include?(k) }
    end
    def wrapper_html_options
      super.merge(:class =&amp;gt; "#{super[:class]} special-class" )
    end
  end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Thank you, Ruby!&lt;/p&gt;
	&lt;p&gt;Maybe you want to alter &lt;code&gt;EmailInput&lt;/code&gt; so that it always includes some fluffy hint text about privacy, and maybe some placeholder text. In other words, you want to define what &lt;em&gt;your&lt;/em&gt; app needs from an email input, so that you don’t have to repeat yourself all over the app. Easy:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  class EmailInput &amp;lt; Formtastic::Inputs::EmailInput
    def hint_text
      "Trust us, we never send spam and never share your email address with others."
    end
    def placeholder_text
      "you@yours.com"
    end
  end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Here’s the awesome bit. You can create your &lt;em&gt;own&lt;/em&gt; custom inputs in the same way. Here’s a few ideas:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;subclass &lt;code&gt;NumberInput&lt;/code&gt; to create an &lt;code&gt;AgeInput&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;subclass &lt;code&gt;StringInput&lt;/code&gt; to create a jQuery &lt;code&gt;DatepickerInput&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;redefine &lt;code&gt;DateTimeInput&lt;/code&gt; to be way less complicated than it is right now (perhaps as a HTML5 date picker with Javascript fallback?)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;This stuff is in &lt;a href="https://github.com/justinfrench/formtastic"&gt;the master branch on Github&lt;/a&gt; right now. If you’ve got a little app in development, now would be a great time to take it for a spin and give me some feedback — simply bundle Formtastic from the master branch directly with the &lt;code&gt;:git&lt;/code&gt; option, have a play, then switch back to the gem.&lt;/p&gt;
	&lt;p&gt;Perhaps now is a great time to shamelessly plug the &lt;a href="http://www.pledgie.com/campaigns/2178"&gt;Pledgie campaign&lt;/a&gt;? I’m doing this for myself, but it’d be great to know I’m also doing it for you, your boss or your clients as well.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/qFpNIVfugic" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I’ve been pouring more hours than I care to admit into a massive refactor of Formtastic. I’m really happy with where it’s headed, so it’s time to share some of the goodies!&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-2-preview-custom-inputs</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-01-12T21:04:29Z</published>
		<updated>2011-01-12T21:04:29Z</updated>
		<title>Formtastic 2 will drop Rails 2 support</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/p4si1bgd_oE/formtastic-2-will-drop-rails-2-support" />
		<id>tag:justinfrench.com,2011-01-12:083bed6ad50451eb341a307b6c00ee12/396e4c005a4c213c060f40a2c7d79f84</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;It’s time. I’m getting pretty excited about getting stuck into &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt; 2.0, and the first step is to free us from the baggage — a bunch of code, documentation and limitations that will slow us down.&lt;/p&gt;
	&lt;p&gt;Last night I branched off master and got to work in the &lt;a href="https://github.com/justinfrench/formtastic/tree/kill-rails-2"&gt;kill-off-rails-2 branch&lt;/a&gt; which I just pushed up to Github.&lt;/p&gt;
	&lt;p&gt;I’m going to merge this into master really soon, so the edge is about to get bumpy. If you’re bundling Formtastic directly from the master branch using the &lt;code&gt;:git&lt;/code&gt; option, now would be a really great time to switch to the &lt;a href="https://github.com/justinfrench/formtastic/tree/1.2-stable"&gt;1.2-stable branch&lt;/a&gt; (or any known stable commit) using the &lt;code&gt;:branch&lt;/code&gt; option.&lt;/p&gt;
	&lt;p&gt;If you want to help out, please test this new branch against your application by temporarily bundling it in with the &lt;code&gt;:git&lt;/code&gt; and &lt;code&gt;:branch&lt;/code&gt; options. In particular, it’d be nice to know that the more complex parts of Formtastic (like nested attributes) still work as expected.&lt;/p&gt;
	&lt;p&gt;If you spot any unnecessary code or tests that can now be removed or refactored, let me know or send a patch!&lt;/p&gt;
	&lt;p&gt;For those still working with Rails 2 apps (myself included), Formtastic 1.x will be maintained for bug fixes and minor refinements for a while yet in the &lt;a href="https://github.com/justinfrench/formtastic/tree/1.2-stable"&gt;1.2-stable branch&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;Now would be a great time to make sure you’re bundling or requiring the appropriate version of Formtastic in your application to avoid nasty surprises when beta releases or incompatible versions start shifting!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/p4si1bgd_oE" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;It’s time. I’m getting pretty excited about getting stuck into &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt; 2.0, and the first step is to free us from the baggage.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-2-will-drop-rails-2-support</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2011-01-10T19:48:10Z</published>
		<updated>2011-01-10T19:48:10Z</updated>
		<title>Silencing Deprecation Warnings in Rspec</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/GM3p_3NlnV8/silencing-deprecation-warnings-in-rspec" />
		<id>tag:justinfrench.com,2011-01-10:083bed6ad50451eb341a307b6c00ee12/5b0782b067f3474a1629101938d37289</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;If you’re testing the behavior of deprecated code in your Ruby project, the warning messages littered throughout your spec output is incredibly noisy.&lt;/p&gt;
	&lt;p&gt;You could silence all warnings with &lt;code&gt;::ActiveSupport::Deprecation.silenced = true&lt;/code&gt;, but you might miss out on an important warning in one of your dependencies. It’s tempting to remove the tests altogether (the code will be burned soon too, right?), but I figured out something a little nicer a little while back in Formtastic’s test suite.&lt;/p&gt;
	&lt;p&gt;Throw this code in &lt;code&gt;spec/support/deprecations.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def with_deprecation_silenced(&amp;block)
  previous_setting = ::ActiveSupport::Deprecation.silenced
  ::ActiveSupport::Deprecation.silenced = true
  yield
  ::ActiveSupport::Deprecation.silenced = previous_setting
end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;You can then wrap that block around almost any part of your test suite to temporarily turn off the deprecation warnings. Here’s an example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe '#bah' do
  with_deprecation_silenced do
    it 'should be deprecated' do
      ::ActiveSupport::Deprecation.should_receive(:warn).any_number_of_times
      Foo.new.bah
    end
    it 'should return true' do
      Foo.new.bah.should be_true
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Better still, I recently discovered that ActiveSupport already has method for this, but it’s currently hidden in the Rails documentation (it’ll be fixed in next stable release). So I can change my code to something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;def with_deprecation_silenced(&amp;block)
  ::ActiveSupport::Deprecation.silence do
    yield
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Alternatively, we could just use the ActiveSupport method directly in our tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe '#bah' do
  ::ActiveSupport::Deprecation.silence do
    it 'should be deprecated' do
      ::ActiveSupport::Deprecation.should_receive(:warn).any_number_of_times
      Foo.new.bah
    end
    it 'should return true' do
      Foo.new.bah.should be_true
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;The (lesser) alternative would be to roll your own in RSpec’s &lt;code&gt;before&lt;/code&gt; and &lt;code&gt;after&lt;/code&gt; blocks:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;describe '#bah' do 
  before do
    @old_silence_config = ::ActiveSupport::Deprecation.silenced
    ::ActiveSupport::Deprecation.silenced = true
  end
  #...
  after do
    ::ActiveSupport::Deprecation.silenced = @old_silence_config
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;This is one of the many simple reasons why I love Ruby’s blocks!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/GM3p_3NlnV8" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;If you’re testing the behavior of deprecated code in your Ruby project, the warning messages littered through your test output is incredibly noisy. I recently figured out something a little nicer in Formtastic’s test suite.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/silencing-deprecation-warnings-in-rspec</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-11-13T06:55:07Z</published>
		<updated>2010-11-13T06:55:07Z</updated>
		<title>Formtastic 1.2.0</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/0gZGEnbBp9k/formtastic-120" />
		<id>tag:justinfrench.com,2010-11-13:083bed6ad50451eb341a307b6c00ee12/dfead991ce911d85cf5f24807174cba2</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;I’m really excited to announce the 1.2.0 release of &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt;. As usual, this was a massive team effort with help from nearly 20 contributors. My thanks to everyone for their help, especially new contributors like &lt;a href="http://github.com/asanghi"&gt;Aditya Sanghi&lt;/a&gt;, who powered through 29 commits, including a bunch of new HTML5 inputs.&lt;/p&gt;
	&lt;h3&gt;Upgrading&lt;/h3&gt;
	&lt;p&gt;Don’t forget to (re-)run the installation generator to make sure you have an up-to-date formtastic.css with many fixes and improvements.&lt;/p&gt;
&lt;pre&gt;
  # Rails 3:
  $ rails generate formtastic:install 
  # Or Rails 2:
  $ ./script/generate formtastic 
&lt;/pre&gt;
	&lt;h3&gt;New Stuff&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Added support for Paperclip’s questionable use of multiple error keys on a single attribute, so errors on Paperclip &lt;code&gt;:file&lt;/code&gt; inputs Just Work™&lt;/li&gt;
		&lt;li&gt;Added ability for the error and hint class to be overridden with &lt;code&gt;:hint_class&lt;/code&gt; and &lt;code&gt;:error_class&lt;/code&gt;, and configurable defaults app-wide&lt;/li&gt;
		&lt;li&gt;Added basic support for multiple forms in the same document by allowing the element ids to be prefixed with the :namespace option on &lt;code&gt;semantic_form_for&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Added a fallback to Rails’ &lt;code&gt;helpers.label&lt;/code&gt; key if Formtastic label translation are not found&lt;/li&gt;
		&lt;li&gt;Added support for &lt;code&gt;default_text_area_width&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Added support for &lt;code&gt;#persisted?&lt;/code&gt; over &lt;code&gt;#new_record?&lt;/code&gt; (ActiveModel)&lt;/li&gt;
		&lt;li&gt;Added the ‘required’ logic to attributes with &lt;code&gt;validates_inclusion_of&lt;/code&gt; validation, in addition to &lt;code&gt;validates_presence_of&lt;/code&gt; &lt;/li&gt;
		&lt;li&gt;Added new HTML5 &lt;code&gt;:as =&amp;gt; :email&lt;/code&gt; input (Rails 3)&lt;/li&gt;
		&lt;li&gt;Added new HTML5 &lt;code&gt;:as =&amp;gt; :phone&lt;/code&gt; input (Rails 3)&lt;/li&gt;
		&lt;li&gt;Added new HTML5 &lt;code&gt;:as =&amp;gt; :search&lt;/code&gt; input (Rails 3)&lt;/li&gt;
		&lt;li&gt;Added new HTML5 &lt;code&gt;:as =&amp;gt; :url&lt;/code&gt; input (Rails 3)&lt;/li&gt;
		&lt;li&gt;Added the ability for the &lt;code&gt;:collection&lt;/code&gt; option to accept a string of HTML (like the output from &lt;code&gt;grouped_options_for_select&lt;/code&gt;), rather than just Arrays, Hashes, collections, etc.&lt;/li&gt;
		&lt;li&gt;Added the ability to set your own form class, instead of ‘formtastic’&lt;/li&gt;
		&lt;li&gt;Added &lt;code&gt;maxlength&lt;/code&gt; attributes to inputs if it can be determined via the ValidationReflection plugin or ActiveModel validation reflections&lt;/li&gt;
		&lt;li&gt;Added the ability to override the form class (Post =&gt; “post”) through an &lt;code&gt;:as&lt;/code&gt; option on &lt;code&gt;semantic_form_for&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Added the ability to customize the order for specific types of inputs. This is configured on a type basis and if a type is not found it will fall back to the default order as defined by the &lt;code&gt;inline_order&lt;/code&gt; config&lt;/li&gt;
		&lt;li&gt;Added &lt;code&gt;:first&lt;/code&gt; as a new rendering choice for the errors on each input&lt;/li&gt;
		&lt;li&gt;Added &lt;code&gt;custom_inline_order&lt;/code&gt; to allow inline ordering per input type&lt;/li&gt;
		&lt;li&gt;Added the ability to override the generator templates in Rails 3&lt;/li&gt;
		&lt;li&gt;Added &lt;code&gt;:wrapper_html&lt;/code&gt; functionality to &lt;code&gt;commit_button()&lt;/code&gt; to match what &lt;code&gt;input()&lt;/code&gt; does&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Fixes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed invalid HTML generated by Rails’ hidden inputs on checkboxes (by rendering our own hidden tag in a more deliberate place)&lt;/li&gt;
		&lt;li&gt;Fixed a bunch of invalid i18n key defaults&lt;/li&gt;
		&lt;li&gt;Fixed that ‘required’ classes and logic were not being applied to &lt;code&gt;:check_boxes&lt;/code&gt; and &lt;code&gt;:radio&lt;/code&gt; inputs&lt;/li&gt;
		&lt;li&gt;Fixed CSS bugs around Firefox’s quirks with form elements that resulted in overflow/scroll bar issues&lt;/li&gt;
		&lt;li&gt;Fixed that errors on fields with association were not marking the wrapping tag with the error class&lt;/li&gt;
		&lt;li&gt;Fixed CSS where FF was displaying extra scroll bars on &lt;code&gt;.check_boxes&lt;/code&gt; and &lt;code&gt;.radio&lt;/code&gt; inputs (and the choices within them)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Changes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Changed that we were defaulting to a &lt;code&gt;:select&lt;/code&gt; input for columns ending in &lt;code&gt;_id&lt;/code&gt;, instead of columns with an appropriate associations&lt;/li&gt;
		&lt;li&gt;Changed the width styling for &lt;code&gt;:text&lt;/code&gt;, &lt;code&gt;:string&lt;/code&gt;, &lt;code&gt;:numeric&lt;/code&gt;, &lt;code&gt;:password&lt;/code&gt; and other basic inputs, defaults to 75% unless the &lt;code&gt;size&lt;/code&gt; or &lt;code&gt;cols&lt;/code&gt; attribute is present&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:string&lt;/code&gt;, &lt;code&gt;:numeric&lt;/code&gt;, &lt;code&gt;:password&lt;/code&gt; and other basic inputs’ default text field size config to nil instead of &lt;code&gt;50&lt;/code&gt;, meaning the size attribute will be ommitted from most inputs, makeing styling easier, and custom sizes with the size attribute more deliberate&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:string&lt;/code&gt;, &lt;code&gt;:numeric&lt;/code&gt;, &lt;code&gt;:password&lt;/code&gt; and other basic inputs to no longer add the size attribute based on column information (the default config is applied, unless it’s &lt;code&gt;nil&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:text&lt;/code&gt; input css behaviour updated to be similar to string etc&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:text&lt;/code&gt; inputs to no longer include a default cols attribute, specify it with &lt;code&gt;:input_html&lt;/code&gt; if you need it, but the value we were using was useless&lt;/li&gt;
		&lt;li&gt;Removed &lt;code&gt;:label&lt;/code&gt; calls from the generated ERB in the form generator (i18n is preferred)&lt;/li&gt;
		&lt;li&gt;Changed that &lt;code&gt;:select&lt;/code&gt; inputs for HABTM associations would ignore the &lt;code&gt;:include_blank&lt;/code&gt; option&lt;/li&gt;
		&lt;li&gt;Changed the default method on collections from &lt;code&gt;Model.find(:all)&lt;/code&gt; to &lt;code&gt;Model.all&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;Removed the deprecated &lt;code&gt;formtastic_stylesheets&lt;/code&gt; generator&lt;/li&gt;
		&lt;li&gt;Changed the minimum Rails version to 2.3.7, which the earliest version which the specs pass with&lt;/li&gt;
		&lt;li&gt;Changed &lt;code&gt;:password&lt;/code&gt; inputs to be sized by percentage (like other string-ish inputs), rather then em-based&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Deprecations&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;Deprecated the :class option on &lt;code&gt;commit_button()&lt;/code&gt;, use &lt;code&gt;:wrapper_html =&amp;gt; { :class =&amp;gt; 'foo' }&lt;/code&gt; instead&lt;/li&gt;
		&lt;li&gt;Deprecated a bunch of aliased method names that should no longer be used&lt;/li&gt;
		&lt;li&gt;Removed &lt;code&gt;:selected&lt;/code&gt;, &lt;code&gt;:checked&lt;/code&gt; and &lt;code&gt;:default&lt;/code&gt; options deprecated in earlier releases&lt;/li&gt;
	&lt;/ul&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/0gZGEnbBp9k" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I’m really excited to announce the 1.2.0 release of Formtastic. As usual, this was a massive team effort with help from nearly 20 contributors.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-120</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-10-19T10:21:15Z</published>
		<updated>2010-10-19T10:21:15Z</updated>
		<title>Activo + Formtastic</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/nM2XFcBZHP4/activo-formtastic" />
		<id>tag:justinfrench.com,2010-10-19:083bed6ad50451eb341a307b6c00ee12/a1660e2e2609e5ac386ec891819967bb</id>
		<category term="Formtastic" />
		<category term="CSS" />
		<content type="html">
	&lt;p&gt;I’m thrilled to see &lt;a href="http://dmfrancisco.github.com/activo/demo/activo.html#block-formtastic"&gt;this live demo&lt;/a&gt; of &lt;a href="http://dmfrancisco.github.com/activo/"&gt;Activo&lt;/a&gt; by David Francisco including support for Formtastic, proving that you can style Formtastic’s markup to achieve great looking forms that look &lt;em&gt;quite different&lt;/em&gt; to the basic ones I supply, all using the same mark-up, relying on the same tags, classes and element ids as everyone else.&lt;/p&gt;
	&lt;p&gt;If you’re working on a web app with Formtastic (come on, there are thousands of you!), I’d &lt;em&gt;love&lt;/em&gt; to see how far you’ve pushed the markup with your own styles and scripting. &lt;a href="http://twitter.com/justinfrench"&gt;Tweet me!&lt;/a&gt;&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/nM2XFcBZHP4" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/activo-formtastic</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-09-24T07:04:00Z</published>
		<updated>2010-09-24T07:09:14Z</updated>
		<title>CSS3's :not Selector</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/GAEMwl0LSJI/css3s-not-selector" />
		<id>tag:justinfrench.com,2010-09-24:083bed6ad50451eb341a307b6c00ee12/cf5321c6c650132e2095c7652c1d99f4</id>
		<category term="CSS" />
		
		<content type="html">
	&lt;p&gt;I’ve been experimenting with some of the new &lt;a href="http://www.w3.org/TR/css3-selectors/"&gt;CSS3 selectors&lt;/a&gt;, admiring IE9’s new &lt;a href="http://kimblim.dk/css-tests/selectors/"&gt;selector support&lt;/a&gt; (finally!) and tinkering with JavaScript libraries like &lt;a href="http://selectivizr.com"&gt;Selectivizr&lt;/a&gt; and &lt;a href="http://code.google.com/p/ie7-js/"&gt;IE7.js&lt;/a&gt; to see if they can help drag older versions of IE into the future kicking and screaming.&lt;/p&gt;
	&lt;p&gt;The &lt;code&gt;:not&lt;/code&gt; selector helped me solve a pretty common problem today. We had a pretty standard unordered list, and we wanted to place a one pixel border in between each list item. Let’s start with the unsurprising mark-up:&lt;/p&gt;
&lt;pre&gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;Cats&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;Dogs&amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;Mice&amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&lt;/pre&gt;
	&lt;p&gt;A common solution is to place a border-bottom on each &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
  ul li {
    border-bottom: 1px solid #ccc;
  }
&lt;/pre&gt;
	&lt;p&gt;This doesn’t just place a border &lt;em&gt;between&lt;/em&gt; each list item of course, it also adds a border after the last item. Something like this:&lt;/p&gt;
	&lt;p&gt;&lt;img src="/images/9.png" alt="" /&gt;&lt;/p&gt;
	&lt;p&gt;Sometimes this isn’t what I want, but I have options. I can use the &lt;code&gt;:last-child&lt;/code&gt; pseudo selector to &lt;em&gt;remove&lt;/em&gt; the border on the last list item:&lt;/p&gt;
&lt;pre&gt;
  ul li {
    border-bottom: 1px solid #ccc;
  }
  ul li:last-child {
    border-bottom:none;
  }
&lt;/pre&gt;
	&lt;p&gt;IE6 doesn’t support this selector, so IE6 users will end up seeing that last border. Graceful degradation for the win, right? Sometimes this is acceptable, sometimes it isn’t. In some designs, I can work around this by repeating the same border on the top, left and right borders of the &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt;, creating a border the whole way around the list.&lt;/p&gt;
&lt;pre&gt;
  ul {
    border:1px solid #ccc;
    border-bottom:none;
  }
  ul li {
    border-bottom: 1px solid #ccc;
  }
&lt;/pre&gt;
	&lt;p&gt;Which results in something like this:&lt;/p&gt;
	&lt;p&gt;&lt;img src="/images/11.png" alt="" /&gt;&lt;/p&gt;
	&lt;p&gt;If that’s not going to work in the design, the next crutch I usually reach for is adding a &lt;code&gt;last&lt;/code&gt; class to the last item in the list that I can hook into to remove the bottom border in all browsers:&lt;/p&gt;
&lt;pre&gt;
  ul li {
    border-bottom: 1px solid #ccc;
  }
  ul li.last {
    border-bottom: none;
  }
&lt;/pre&gt;
	&lt;p&gt;This bugs me for a few reasons:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;We’ve added markup to the page purely for presentational reasons.&lt;/li&gt;
		&lt;li&gt;I like writing code that’s easy for my co-workers to read and understand. In this case, we had to  describe the one presentational goal (“put a border in between the list items”) with two rules. This means the reader needs to consider &lt;em&gt;both&lt;/em&gt; rules before they can understand what the styles are trying to do. This may seem trivial, but this is a riciculously simple example — real world examples would probably have margins, padding, typography and hover styles adding noise.&lt;/li&gt;
		&lt;li&gt;It’s code that’s looking &lt;em&gt;backwards&lt;/em&gt; instead of &lt;em&gt;forwards&lt;/em&gt;. We’re cluttering everything up to support an older browser which still a big deal for some websites. &lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;This is where &lt;code&gt;:not&lt;/code&gt; can help us! Here’s what I came up with:&lt;/p&gt;
&lt;pre&gt;
  ul li:not(:last-child) {
    border-bottom: 1px solid #ccc;
  }
&lt;/pre&gt;
	&lt;p&gt;Bam! That’s one simple rule that describes the visual treatment perfectly. No extra markup, no extra styles. Here’s what it looks like in IE9 and all other modern browsers:&lt;/p&gt;
	&lt;p&gt;&lt;img src="/images/10.png" alt="" /&gt;&lt;/p&gt;
	&lt;p&gt;Perfect! The trade-off, of course, is that older browsers like IE 6, 7 and 8 don’t understand &lt;code&gt;:not&lt;/code&gt; (or &lt;code&gt;:last-child&lt;/code&gt; for that matter). How did I decide that this was an acceptable trade-off?&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;We have a eight of developers, all contributing in the view layer, but only a few of us spend time &lt;em&gt;really&lt;/em&gt; testing the interface in all the browsers, and even fewer would spot that extra border on the bottom list item and realize that something wasn’t quite right.&lt;/li&gt;
		&lt;li&gt;In the design we were working on, the list looked &lt;em&gt;horrible&lt;/em&gt; in IE6 with that extra line — It wasn’t a &lt;em&gt;gracefull degradation&lt;/em&gt;, it was an ugly line in the wrong place screwing up my design. We have a heap of IE6 users still, so this matters.&lt;/li&gt;
		&lt;li&gt;The list actually looked pretty good in IE 6/7/8 &lt;em&gt;without&lt;/em&gt; the borders.&lt;/li&gt;
		&lt;li&gt;Less markup and less CSS means there’s less chance of screwing things up, and it just feels &lt;em&gt;wrong&lt;/em&gt; to write extra markup or CSS to deal with a browser that was released nearly &lt;em&gt;ten years ago&lt;/em&gt;.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;So, for this particular design, with this team, with this set of users, with this web app, it turns out that &lt;em&gt;progressive enhancement&lt;/em&gt; with a modern browser feature worked better than &lt;em&gt;graceful degradation&lt;/em&gt; for an older browser. It might work for you too.&lt;/p&gt;
	&lt;p&gt;You can have your cake and eat it too! The really great news is that if you add-in something like &lt;a href="http://selectivizr.com"&gt;Selectivizr&lt;/a&gt; with an IE-ony conditional comment, most of your IE6/7/8 users can also come to the party with an 8kb Javascript download.&lt;/p&gt;
	&lt;p&gt;I feel like I’m just scratching the surface with the &lt;code&gt;:not&lt;/code&gt; selector. If you have some ideas how it can be used to enhance a design, or know of similar tutorials I should be reading and linking to, &lt;a href="http://twitter.com/justinfrench"&gt;let me know on Twitter&lt;/a&gt;.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/GAEMwl0LSJI" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/css3s-not-selector</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-09-08T06:11:00Z</published>
		<updated>2010-09-08T06:12:18Z</updated>
		<title>Formtastic 1.1 Ships with Rails 3 (and 2) Compatibility</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/fSK87mivMIM/formtastic-11-ships-with-rails-3-and-2-compatibility" />
		<id>tag:justinfrench.com,2010-09-08:083bed6ad50451eb341a307b6c00ee12/f3c6f16d37a0af1c0fd1e4ad18208a47</id>
		<category term="Formtastic" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;I’m very pleased to announce that I finally pulled the lever a few minutes ago, pushing up &lt;a href="http://rubygems.org/gems/formtastic"&gt;Formtastic 1.1 to RubyGems.org&lt;/a&gt;, compatible with both Rails 2 and Rails 3.&lt;/p&gt;
	&lt;p&gt;My thanks go to every one who contributed patches and actively tested our work.&lt;/p&gt;
	&lt;p&gt;Special thanks to Morton Jonuschat and Gabriel Sobrinho for their hard work managing this entire process. Between them, they’ve made 113 commits (and signed off many more from the community), making them the 2nd and 5th highest contributors to the project in a just a few short months.&lt;/p&gt;
	&lt;p&gt;I was able to focus on the 1.0 release, while they quietly worked away in the rails3 branch. It was such a pleasure to be able to just &lt;em&gt;use&lt;/em&gt; Formtastic on my Rails 3 projects, rather than have to &lt;em&gt;build&lt;/em&gt; it.&lt;/p&gt;
	&lt;p&gt;There were no code changes between the 1.1.0.beta and today’s release (only documentation changes), so this will be a pain-free upgrade for those running the betas.&lt;/p&gt;
	&lt;p&gt;If you’re upgrading from 1.0 or earlier, there’s been over 140 significant changes to the code in order to support both Rails 2 and Rails 3, but these were internal changes only — there should be no changes to the API or functionality. Run your tests, check how things are working for yourself, of course.&lt;/p&gt;
	&lt;p&gt;We’ve had had two major forks in the code for a while (master for 1.0.x and master for 1.1.0), but this will soon change. There’s a 1.0-stable branch for any maintenance work we need to do, and rails3 will be merged into master in a few days.&lt;/p&gt;
	&lt;p&gt;We’ll be doing some housekeeping for a bit, then jumping into new features and some deprecations for a 1.2 release as soon as possible.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/fSK87mivMIM" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I’m very pleased to announce that I finally pulled the lever a few minutes ago, pushing up Formtastic 1.1 to RubyGems.org, compatible with both Rails 2 and Rails 3.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-11-ships-with-rails-3-and-2-compatibility</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-08-23T23:49:20Z</published>
		<updated>2010-08-23T23:49:20Z</updated>
		<title>Readme Driven Development</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/8CxF4tPAsnc/readme-driven-development" />
		<id>tag:justinfrench.com,2010-08-23:083bed6ad50451eb341a307b6c00ee12/c1670062901e6a2808ac553fc76f0669</id>
		<category term="Design" />
		<category term="Agile" />
		<content type="html">
	&lt;p&gt;In &lt;a href="http://tom.preston-werner.com/2010/08/23/readme-driven-development.html"&gt;Readme Driven Development&lt;/a&gt;, Tom Preston-Werner advocates writing the README file before any code is written, and indeed, before any tests are written.&lt;/p&gt;
	&lt;p&gt;I couldn’t agree more. This is exactly what I did with &lt;a href="http://github.com/justinfrench/formtastic.git"&gt;Formtastic&lt;/a&gt;. I designed the DSL and how I thought programmers &lt;em&gt;should&lt;/em&gt; build forms long before I wrote any code.&lt;/p&gt;
	&lt;p&gt;I think this has had a huge impact on the success of Formtastic so far. People may dislike the underlying mark-up choices I made, or the underlying code implementation (which definitely needs some TLC), or the lack of in-depth documentation, but for the most part, people &lt;em&gt;love&lt;/em&gt; the DSL.&lt;/p&gt;
	&lt;p&gt;José Valim even proudly choose to replicate the Formtastic DSL in &lt;a href="http://github.com/plataformatec/simple_form"&gt;simple_form&lt;/a&gt; his own form builder for Plataformatec.&lt;/p&gt;
	&lt;p&gt;What Tom is really advocating is a small amount of up front design to figure out how people will use your software in order to give it vision and clarity &lt;em&gt;before&lt;/em&gt; you start pumping out code. A README file is cheap. Code is relatively expensive.&lt;/p&gt;
	&lt;p&gt;Here’s a quote from 37 Signals’ &lt;a href="http://gettingreal.37signals.com/ch09_Interface_First.php"&gt;Interface First&lt;/a&gt; in &lt;em&gt;Getting Real&lt;/em&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;We start with the interface so we can see how the app looks and feels from the beginning. It’s constantly being revised throughout the process. Does it make sense? Is it easy to use? Does it solve the problem at hand? These are questions you can only truly answer when you’re dealing with real screens. Designing first keeps you flexible and gets you to those answers sooner in the process rather than later.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;It’s ridiculously easy to draw comparisons here. Design your library’s interface first!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/8CxF4tPAsnc" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/readme-driven-development</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-08-11T23:32:02Z</published>
		<updated>2010-08-11T23:32:02Z</updated>
		<title>Formtastic 1.0 Release</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/qlnFAEQ6vlA/formtastic-10-release" />
		<id>tag:justinfrench.com,2010-08-11:083bed6ad50451eb341a307b6c00ee12/b112dbc27f7d373fd1605c9a33217e55</id>
		<category term="Formtastic" />
		<category term="Ruby" />
		<content type="html">
	&lt;p&gt;After promising we’re “deliciously close to a 1.0” for about a year, this has been a long time coming.&lt;/p&gt;
	&lt;p&gt;Formtastic 1.0 is compatible with Rails 2.x. For those of you working with Rails 3, there’s a rails3 branch (aiming to be compatible with both Rails 2.x and 3.x) on Github, and we hope to ship a 1.1.0.beta gem in the next week or so from this branch.&lt;/p&gt;
	&lt;p&gt;From here on, I’d like to adhere &lt;a href="http://semver.org/"&gt;Semantic Versioning&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;If you haven’t been playing with the betas and release candidates (shame on you!), here’s a quick re-cap of what’s changed since 0.9.10:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed that &lt;code&gt;:label=&amp;gt;false&lt;/code&gt; didn’t disable the label on checkboxes &amp; radio buttons&lt;/li&gt;
		&lt;li&gt;Added full support of &lt;code&gt;:input_html&lt;/code&gt; options for hidden fields&lt;/li&gt;
		&lt;li&gt;Fixed that &lt;code&gt;:checked_value&lt;/code&gt; and &lt;code&gt;:unchecked_value&lt;/code&gt; options were being passed down into the HTML tags as attributes &lt;/li&gt;
		&lt;li&gt;ensure i18n &lt; 0.4 is listed as a dependency in the gemspec&lt;/li&gt;
		&lt;li&gt;Added &lt;code&gt;:ignore_date&lt;/code&gt; option to time inputs&lt;/li&gt;
		&lt;li&gt;Fixed some issues with the default error proc&lt;/li&gt;
		&lt;li&gt;Added default escaping of html entities in labels and hints&lt;/li&gt;
		&lt;li&gt;Added/fixed that &lt;code&gt;:value_method&lt;/code&gt; and &lt;code&gt;:label_method&lt;/code&gt; were being ignored for simple collections (like an &lt;code&gt;Array&lt;/code&gt;)&lt;/li&gt;
		&lt;li&gt;Added some more compatibility for Mongoid and other ORMs by checking for reflection information before calling it&lt;/li&gt;
		&lt;li&gt;Fixed deprecation warnings in Rails 2.3.6 and newer&lt;/li&gt;
		&lt;li&gt;Fixed a bug where &lt;code&gt;:check_boxes&lt;/code&gt; and &lt;code&gt;:radio&lt;/code&gt; inputs were using the attribute name instead of the &lt;code&gt;:label&lt;/code&gt; option&lt;/li&gt;
		&lt;li&gt;Fixed a conflict where i18n lookups were failing when an attribute and model have the same name&lt;/li&gt;
		&lt;li&gt;Fixed :radio and :check_boxes inputs so that the legend no longer includes a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; with a &lt;code&gt;for&lt;/code&gt; attribute pointing to an input that doesn’t exist&lt;/li&gt;
		&lt;li&gt;Fixed that some inputs had invalid &lt;code&gt;find_options&lt;/code&gt; HTML attribute&lt;/li&gt;
		&lt;li&gt;Fixed that we were calling html_safe! when it was not always available&lt;/li&gt;
		&lt;li&gt;Added the ability for :input_html to now accept an option of :size =&gt; nil, to exclude the :size attribute altogether&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;The really exciting thing for me is that there’s been over 60 contributors to the project. Tools like Github make this easier, but real people donating their time actually makes it work.&lt;/p&gt;
	&lt;p&gt;The community is almost entirely responsible for the rails3 branch too — I started using it for the first time on a new project last month and it was so great to see how far along we are, and most importantly, how little I had to do myself to make it happen.&lt;/p&gt;
	&lt;p&gt;So, thank you all for the support, the bug reports, the patches, the testing, the polishing, the feature requests, the rants, the complaining, the praise, the promotion, the donations and the awesomeness.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/qlnFAEQ6vlA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-10-release</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-07-28T21:58:00Z</published>
		<updated>2010-08-02T11:34:09Z</updated>
		<title>Pagination Alternatives</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/FwgLn6b5HCw/pagination-alternatives" />
		<id>tag:justinfrench.com,2010-07-28:083bed6ad50451eb341a307b6c00ee12/32e97c1c1cd889a9bd7b5d5c5a15ba3c</id>
		<category term="Design" />
		<category term="User-Experience" />
		<content type="html">
	&lt;p&gt;Last night on Twitter, the very awesome Daniel Neighman casually &lt;a href="http://twitter.com/hassox/status/19651231336"&gt;asked&lt;/a&gt; if any of his followers had experience with Rails 3 and the will_paginate plugin. In true Twitter fashion, I &lt;a href="http://twitter.com/justinfrench/status/19651902272"&gt;replied&lt;/a&gt; with an overly simplified and entirely unhelpful “pagination makes baby dolphins cry”. Dan politely &lt;a href="http://twitter.com/hassox/status/19652768685"&gt;asked&lt;/a&gt; “what else should be used?” and Ben Schwarz &lt;a href="http://twitter.com/benschwarz/status/19699696637"&gt;went all out&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;It’s not really about finding a better pattern, it’s about finding the right pattern. Pagination is one of those ubiquitous things on the web. It’s easy to see a pattern like that, apply it to your own “I have too much data to show on one page” problem and take the quick win. Everyone else is doing it, it’s a pattern, you should use it too, right?&lt;/p&gt;
	&lt;p&gt;Pagination really only has two things going for it:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;It’s ubiquitous. Everyone’s seen it before, everyone knows how it works.&lt;/li&gt;
		&lt;li&gt;It’s a quick win. Too much data? Paginate it!&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;There’s a lot not to like:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;It’s &lt;a href="http://patterntap.com/tap/collection/pagination"&gt;usually presented&lt;/a&gt; as an busy set of tiny little links for moving back and forth through the pages, and a series of other tiny links to jump to some (but usually not all) the pages in the set.&lt;/li&gt;
		&lt;li&gt;It’s an interface that’s optimised for use with a mouse. Mouses suck, especially when aiming for tiny targets placed closely next to each other. Easier navigation systems like scroll wheels, keyboard shortcuts, track pads and touch gestures are typically ignored by pagination interfaces.&lt;/li&gt;
		&lt;li&gt;Other sites and search engines will link to “page 4” of your result set, but the specific items will shift to an adjacent page as new items are added.&lt;/li&gt;
		&lt;li&gt;Search engines can penalise your site and ignore many of your pages because you haven’t spent enough time making each page in the set appear different enough.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;There’s almost always an alternative design pattern you can lean on if you take a few minutes to think it through. Here’s some questions you can ask yourself and some ideas you might consider before implementing pagination:&lt;/p&gt;
	&lt;h3&gt;Can you render more items per page, or all of them?&lt;/h3&gt;
	&lt;p&gt;Pagination has a history on the web dating back to dial-up connections and 14k modems. Those days are long behind us, even in the mobile space. Why are we still rendering 10, 20 or 50 items on a page like it’s 1996? What would happen if you just rendered a page with more items? What if you rendered &lt;em&gt;all&lt;/em&gt; the items?&lt;/p&gt;
	&lt;p&gt;For example, I recently took a look at my own &lt;a href="http://justinfrench.com//notebook"&gt;archive&lt;/a&gt; for this website. I changed from 20 items per page to 500, and ensured that the pagination links are only rendered if needed. I have around 200 posts, so the pagination has effectively been removed for now. The resulting page with all 200 posts is around 85k. It took me &lt;em&gt;six years&lt;/em&gt; to write those posts, so it’ll take me a few more to write another 100, at which point the page size might be 150–200k.&lt;/p&gt;
	&lt;p&gt;A few years is a long time on the internet. Bandwidth may triple. I might redesign the entire site and change it’s structure. Anything is possible. This kind of context matters — don’t invent a pagination requirement if there isn’t one.&lt;/p&gt;
	&lt;p&gt;How big will your dataset be next week? How about next year? What’s an acceptable page download for your target audience? Can you just render &lt;em&gt;everything&lt;/em&gt; and revisit this problem later (when it’s actually a problem)?&lt;/p&gt;
	&lt;h3&gt;Can you limit the number of items?&lt;/h3&gt;
	&lt;p&gt;Let’s say you have thousands or even hundreds of thousands of results, like a Google search. Obviously you can’t just send all that down to the browser in one hit. The browser would explode with that many DOM elements and your database is already crying just &lt;em&gt;thinking&lt;/em&gt; about it.&lt;/p&gt;
	&lt;p&gt;I’ve never looked at the 48th page of Google results. I rarely look at the second page and sometimes I don’t even scroll down past the first few results. A search engine is all about relevance, so the second page of results is almost irrelevant by definition, right?&lt;/p&gt;
	&lt;p&gt;Take a look at your server logs or analytics data. Watch people using your software. Understand what they do. If they aren’t clicking beyond the first page you might be able to ditch everything else, limiting the results and negating pagination. If your users aren’t looking beyond page three or page five, experiment with rendering more stuff on the first page and ditching everything else!&lt;/p&gt;
	&lt;h3&gt;Can you find another way to break up the content?&lt;/h3&gt;
	&lt;p&gt;If there’s too many items to render all at once, and it doesn’t make sense to limit the items rendered, try finding another more meaningful way to break up the items into multiple pages. Pagination is the lazy way, giving your users (and search engines) a fragmented view of your content.&lt;/p&gt;
	&lt;p&gt;Think about what your users are really trying to do. They don’t enjoy clicking though page after page of stuff looking for something specific in a series of non-specific pages. If you can find a more specific and meaningful way to break up the data, you’ll improve the user experience, you’ll improve your search ranking and you’ll have smaller sets of data to deal with. Smaller data sets give you more design options and reduce the need for pagination!&lt;/p&gt;
	&lt;p&gt;A chronological list of thousands of events in an activity log is a good example this. If the most important events are the &lt;em&gt;recent&lt;/em&gt; ones, then breaking things up into groups like “today”, “this week”, “this month”, “this year”, “2009” and “2008” might work. Sure, you’ll probably still need pagination on the items in the bigger sets, but you should be able to avoid it for the more common use cases like “what happened this week?”. &lt;/p&gt;
	&lt;p&gt;If you’re working on a financial application, the groups could be relevant to accounting, like “this month”, “last month”, “this quarter”, “last quarter”, “this fiscal year”, “last fiscal year”, etc.&lt;/p&gt;
	&lt;p&gt;Let’s also keep in mind that lots of data is chronological, but most chronological data isn’t &lt;em&gt;only&lt;/em&gt; chronological. &lt;/p&gt;
	&lt;p&gt;For example, many blog archives are broken down into years and months. If I’m trying to find something on your blog, I’m not going to remember that you wrote it in &lt;em&gt;early June 2009&lt;/em&gt;, so a page containing all your posts from that month is kind of useless to me. I’m going to remember that it was related a topic like &lt;em&gt;ruby&lt;/em&gt;, &lt;em&gt;karate&lt;/em&gt; or &lt;em&gt;bacon&lt;/em&gt;. Despite the chronological nature of a blog, it still makes much more sense to me to break up the content by topic (tags, keywords, categories, whatever), resulting in smaller data sets that can probably be rendered without pagination.&lt;/p&gt;
	&lt;h3&gt;Can you implement an endless page?&lt;/h3&gt;
	&lt;p&gt;If all else fails, consider implementing an &lt;em&gt;endless page&lt;/em&gt; like the one found in Google Reader and many other modern web applications. When you load the reader, a limited number of articles are rendered on the screen by default. Let’s say it’s 100 articles, enough to fill the screen. As you scroll down the page, more results are added to the page dynamically through an AJAX request. Keep scrolling down, keep seeing more and more articles.&lt;/p&gt;
	&lt;p&gt;Technically, this is still pagination under the hood, but the end user never sees the pagination interface’s awkward cluster of tiny links.&lt;/p&gt;
	&lt;p&gt;You may have noticed Twitter also does something similar. You have to click a giant “more” link at the bottom of the page, so it’s not quite as magical as Google Reader’s endless page, but it’s still a whole lot better than all those fiddly links and fragmented pages of related content.&lt;/p&gt;
	&lt;h3&gt;Think for yourself&lt;/h3&gt;
	&lt;p&gt;Pagination is still a valid design choice in the right context, but it’s just one option you should explore. Forget about the data schema, the code and the SQL queries for a few minutes and think about your what your users want to achieve. If you really have thousands of items that can’t be broken into smaller groups, and if your users really want to click through it all page-by-page in small chunks, got for it!&lt;/p&gt;
	&lt;h3&gt;Your turn&lt;/h3&gt;
	&lt;p&gt;What are some alternative patterns and interfaces you’ve used instead of pagination? How did you break the data down into smaller chunks? What’s an acceptable page size these days? What are some examples you’ve seen where pagination really &lt;em&gt;is&lt;/em&gt; the right answer? Send them to &lt;a href="http://twitter.com/justinfrench"&gt;@justinfrench&lt;/a&gt;.&lt;/p&gt;
	&lt;h3&gt;Updates, Tweets, Questions and Answers&lt;/h3&gt;
	&lt;p&gt;&lt;strong&gt;@russell &lt;a href="http://twitter.com/russell/status/19780775982"&gt;tweeted&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Wondering what @justinfrench &amp; @xshay think about ‘next’ and ‘prev’ links without the 1234567… pagination in between.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;It depends! Assuming pagination is your only real choice (not convinced, but whatever), and there’s no real need for your users to jump to “page 7” in a non-linear path, then yes, get rid of those numbered links! &lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;@grigi0 &lt;a href="http://twitter.com/grigi0/status/19811100221"&gt;tweeted&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;you are right about pagination on the searches, but maybe it is the only option on forum thread because pages are “static”&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Forums are a good example that probably needs to be paged through. However, forums get over used for a bunch of very different use cases (because they’re “cheap”) — everything from endless unfocused discussion through to questions and answers on a focused topic. It’d be interesting to think about some interface alternatives based on what people really use a forum for. I’ll write a follow-up post on this I think! &lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;@sgruhier &lt;a href="http://twitter.com/sgruhier/status/19808035656"&gt;tweeted&lt;/a&gt;:&lt;/strong&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;If you have a geo-localized data, you can think of displaying all of them on a map&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Absolutely, a map is another great example. Geographical information opens many new ways to break up the data, and you can add more data points as you zoom in on a smaller area. Countries and regions are obvious, but there’s bigger opportunities like “near me” or “near the hotel I’m staying at next week”, that can be combined with zooming in for more data.&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;@CorinCole &lt;a href="http://twitter.com/CorinCole/status/19963628155"&gt;tweeted&lt;/a&gt;&lt;/strong&gt; his dislike of “endless pages” and Twitter’s Ajax-powered “more” button because they make it hard to directly link to something on the Nth page. This is true if a lazy developer doesn’t &lt;a href="http://ajaxpatterns.org/Unique_URLs"&gt;provide a unique URL&lt;/a&gt; for the “page” you’re viewing, but like I said, this is really just pagination with a slightly different UI (scrolling, or a single button). Pagination is a “if all else fails…” thing. I’m pretty sure you can do better.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/FwgLn6b5HCw" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Pagination is one of those ubiquitous things on the web. It’s easy to see a pattern like that, apply it to your own “I have too much data to show on one page” problem and take the quick win. Everyone else is doing it, it’s a pattern, you should use it too, right?&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/pagination-alternatives</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-07-26T10:11:23Z</published>
		<updated>2010-07-26T10:11:23Z</updated>
		<title>Six Years of justinfrench.com</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/CbyI-V83Pnk/six-years-of-justinfrenchcom" />
		<id>tag:justinfrench.com,2010-07-26:083bed6ad50451eb341a307b6c00ee12/ed068e527d07d0fd54b2c0dc8026ca97</id>
		<category term="Me" />
		<category term="This Site" />
		<content type="html">
	&lt;p&gt;At some particularly nerdy moment, I set-up an iCal reminder for the birthday of this website. A few hours from now, justinfrench.com will be 6 years old!&lt;/p&gt;
	&lt;p&gt;The first year or two was a whole lot of fun — I was experimenting a lot with web standards, pushing hard for CSS replace the crazy shit we were pulling with tables, wrestling with browsers a whole lot more than we have to now, playing with new text editors like TextMate, shifting away from PHP to languages like Ruby, and waiting for Apple to open an iTunes store in Australia. I also made the most important leap of faith in my career, closing up my freelancing business to help Dean Allen, Jason Hoffman and a bunch of other incredibly smart people build a tiny little hosting company called TextDrive.&lt;/p&gt;
	&lt;p&gt;So much has happened. TextDrive was acquired by Joyent, RedBubble lured me out of my home office and into my first Australian start-up building a massive online creative community, the guys at Clear asked me to help re-shape the Australian grain market with a trading platform, and a bunch of New Zealanders acquired Clear. I got married! We had a kid!&lt;/p&gt;
	&lt;p&gt;I pushed myself in a heap of new directions at work (from design and code to agile project management and a five month stint as interim CTO at Clear) and found out a whole lot more about what makes me tick than I ever would freelancing from my home office in the ‘burbs.&lt;/p&gt;
	&lt;p&gt;There’s a bunch of other stuff, too much to mention, half I which I never wrote about. I’m a bit down that I let this website slide. I still love the design (it’s unheard of for a blog to go so long without a redesign!), but I’ve been horribly lazy when it comes to writing about the things I’m learning every day.&lt;/p&gt;
	&lt;p&gt;There’s been a few bursts where I tried to kick-start regular writing, but something else always seems to be a bit further up on the priority list. I’d like to say things will change, but we’ll see.&lt;/p&gt;
	&lt;p&gt;Either way, it’s been amazing six years, and I feel like we’re only just getting started. I love making things, and this is a great time to be doing that.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/CbyI-V83Pnk" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/six-years-of-justinfrenchcom</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-06-07T03:54:00Z</published>
		<updated>2010-06-07T03:55:52Z</updated>
		<title>Formtastic 1.0.0.beta Released</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/U8ZlDe3UY40/formtastic-100beta-released" />
		<id>tag:justinfrench.com,2010-06-07:083bed6ad50451eb341a307b6c00ee12/b5cdd769038df8f76570217e062b040c</id>
		<category term="Rails" />
		<category term="Ruby" />
		<content type="html">
	&lt;p&gt;I’ve just pushed up the first 1.0 beta gem!&lt;/p&gt;
	&lt;h3&gt;Your mission&lt;/h3&gt;
	&lt;p&gt;Download the beta, install it in your Rails 2.x apps, run your test suite, then reply to &lt;a href="http://groups.google.com/group/formtastic/browse_thread/thread/708cf39d1eeb751f"&gt;this thread&lt;/a&gt; with “all good” if your tests pass. If you encounter problems, please create issues on Github, or discuss on the Google Group.&lt;/p&gt;
	&lt;p&gt;There’s only one outstanding 1.0 issue (#246, which we’re still pondering on the solution for, so it’ll probably slip out to 1.2).&lt;/p&gt;
	&lt;h3&gt;What’s changed?&lt;/h3&gt;
	&lt;p&gt;Here’s the CHANGELOG entries since 0.9.10:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Fixed &lt;code&gt;:radio&lt;/code&gt; and &lt;code&gt;:check_boxes&lt;/code&gt; inputs so that the legend no longer includes a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; with a &lt;code&gt;for&lt;/code&gt; attribute pointing to an input that doesn’t exist (#253)&lt;/li&gt;
		&lt;li&gt;Fixed that some inputs had invalid &lt;code&gt;find_options&lt;/code&gt; attribute (#262)&lt;/li&gt;
		&lt;li&gt;Fixed that we were calling &lt;code&gt;html_safe!&lt;/code&gt; when it was not always available&lt;/li&gt;
		&lt;li&gt;Added the ability for &lt;code&gt;:input_html&lt;/code&gt; to now accept an option of &lt;code&gt;:size =&amp;gt; nil&lt;/code&gt;, to exclude the &lt;code&gt;:size&lt;/code&gt; attribute altogether (#267)&lt;/li&gt;
	&lt;/ul&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/U8ZlDe3UY40" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-100beta-released</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-05-26T00:41:00Z</published>
		<updated>2010-05-26T01:37:49Z</updated>
		<title>Formtastic 0.9.9 &amp; 0.9.10 Released</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/bCCJV3fGWJ8/formtastic-099-released" />
		<id>tag:justinfrench.com,2010-05-26:083bed6ad50451eb341a307b6c00ee12/60412857d7abfb568c1c1df5642bf37e</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;I was hoping that the next Formtastic release was a 1.0.beta, but the recent Rails &lt;del&gt;2.3.6&lt;/del&gt; &lt;del&gt;2.3.7&lt;/del&gt; 2.3.8 release spurred us to issue &lt;del&gt;0.9.9&lt;/del&gt; 0.9.10 to maintain compatibility.&lt;/p&gt;
	&lt;p&gt;There were some features added and other changes made since 0.9.8 so here’s the changes:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Changed date/time inputs to default to nil instead of Time.now when the object has no value (due to deprecation warning, #240)&lt;/li&gt;
		&lt;li&gt;Changed the behaviour of associations with a :class_name option to be more consistent with what Rails expects&lt;/li&gt;
		&lt;li&gt;Fixed issues relating to Rails 2.3.6 automatically escaping ERB&lt;/li&gt;
		&lt;li&gt;Fixed issues with Ruby 1.9.1 and Haml&lt;/li&gt;
		&lt;li&gt;Added the :disabled option to check_boxes input&lt;/li&gt;
		&lt;li&gt;Added translation support for nested models (thanks to Toni Tuominen)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;I’d especially like to thank &lt;a href="http://github.com/yabawock"&gt;yabawock&lt;/a&gt; for his ridiculously fast work back-porting some of the changes in our &lt;a href="http://github.com/justinfrench/formtastic/tree/rails3"&gt;rails3 branch&lt;/a&gt; into master for this release. I love this community!&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; We had to push up an 0.9.10 release to fix an i18n incompatibility with Rails 2. Embarrassing, sorry we missed it. If you’re one of the 24 people who installed 0.9.9, please grab 0.9.10!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/bCCJV3fGWJ8" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I was hoping that the next Formtastic release was a 1.0.beta, but the recent Rails &lt;del&gt;2.3.6&lt;/del&gt; &lt;del&gt;2.3.7&lt;/del&gt; 2.3.8 release spurred us to issue 0.9.9 to maintain compatibility.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-099-released</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-03-31T20:01:00Z</published>
		<updated>2010-04-14T05:10:42Z</updated>
		<title>Formtastic 0.9.8</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/eTPexv6ZZMI/formtastic-098" />
		<id>tag:justinfrench.com,2010-03-31:083bed6ad50451eb341a307b6c00ee12/355215ffd5b3caa3ab2a6c2b46228a4a</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;It’s been a long time between drinks, and I’m &lt;em&gt;really&lt;/em&gt; not a fan of releasing this much stuff all at once, but Formtastic 0.9.8 is finally here.&lt;/p&gt;
	&lt;p&gt;Run &lt;code&gt;./script/generate formtastic&lt;/code&gt; if you want to update the stylesheets and configuration files (you have version control, right?).&lt;/p&gt;
	&lt;p&gt;There’s a heap of fixes and a few tiny new features, but the most important thing to know is that the behaviour of the &lt;code&gt;:selected&lt;/code&gt; option has changed to address some bugs and inconsistencies, and that it’s been deprecated due to many issues you can read about in &lt;a href="http://wiki.github.com/justinfrench/formtastic/deprecation-of-selected-option"&gt;the wiki&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;It’s also (still) not Rails 3 compatible, but you may want to try the &lt;a href="http://rubygems.org/gems/formtastic-rails3"&gt;formtastic-rails3&lt;/a&gt; gem (based off 0.9.7) by Rodrigo Alvarez, who’s been doing a lot of work in his fork for Rails 3 compatibility.&lt;/p&gt;
	&lt;p&gt;Here’s the CHANGELOG:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;Deprecated :selected/:checked options, see &lt;a href="http://wiki.github.com/justinfrench/formtastic/deprecation-of-selected-option"&gt;the wiki page&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Changed CSS rules for fieldset lists to be more specific&lt;/li&gt;
		&lt;li&gt;Changed radio and checkbox inputs to no longer associate the legend label with the first choice’s input (#101)&lt;/li&gt;
		&lt;li&gt;Changed the generators to use |f| rather than |form| (#151)&lt;/li&gt;
		&lt;li&gt;Changed the behaviour of :selected/:checked options to address several bugs and inconsistencies (#152)&lt;/li&gt;
		&lt;li&gt;Changed CSS for input width property to max-width, allowing a size attribute to still be set&lt;/li&gt;
		&lt;li&gt;Fixed an issue where label_str_method not honoured if the object is an ActiveRecord object&lt;/li&gt;
		&lt;li&gt;Fixed incorrect html class for namespaced objects (”/” replaced with ”_”)&lt;/li&gt;
		&lt;li&gt;Fixed compatibility issue with SearchLogic (#155)&lt;/li&gt;
		&lt;li&gt;Fixed an issue where label_str_method was not being overridden with i18n&lt;/li&gt;
		&lt;li&gt;Fixed a button text issue with Rails 2.x in which human_name on multi-word models returned one word (eg Ticketrequest) (#153)&lt;/li&gt;
		&lt;li&gt;Fixed the behaviour of select inputs when the belongs_to or has_many association has a special :class_name option&lt;/li&gt;
		&lt;li&gt;Fixed line numbers from eval’d code, to help when debugging&lt;/li&gt;
		&lt;li&gt;Fixed CSS issue that hidden fields were not always hidden (Chrome for example) (#209)&lt;/li&gt;
		&lt;li&gt;Fixed and improved CSS with nested fieldsets and legends&lt;/li&gt;
		&lt;li&gt;Fixed date/time inputs where :include_seconds =&gt; true&lt;/li&gt;
		&lt;li&gt;Fixed that inline hints were still being rendered on hidden inputs&lt;/li&gt;
		&lt;li&gt;Fixed broken CSS declaration missing a colon&lt;/li&gt;
		&lt;li&gt;Added configuration preferences for row and column attributes on textareas&lt;/li&gt;
		&lt;li&gt;Added semantic_errors helper and CSS (for all errors on an object)&lt;/li&gt;
		&lt;li&gt;Added :filename to the list of @@file_methods, to support carrierwave plugin (#156)&lt;/li&gt;
		&lt;li&gt;Added a Formtastic::LayoutHelper with formtastic_stylesheets helper method for linking to all Formtastic CSS files&lt;/li&gt;
		&lt;li&gt;Added labels option to date/time/datetime fields to customise the label of each part of the set (year, month, etc)&lt;/li&gt;
		&lt;li&gt;Added many improvements to the README and docs&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;The next stop from here is a little unknown. I’m guessing a release this big might need a patch or two, but I’m considering this a 1.0 candidate. Far too many people are using this gem in production for it &lt;em&gt;not&lt;/em&gt; to be considered a 1.0, despite all the features think should be in there.&lt;/p&gt;
	&lt;p&gt;Once we jump over that hurdle, I hope we move forward pretty quickly.&lt;/p&gt;
	&lt;p&gt;Finally, &lt;a href="http://github.com/dennismajor1"&gt;Dennis Major&lt;/a&gt; has been doing some amazing work &lt;a href="http://wiki.github.com/justinfrench/formtastic"&gt;in the wiki&lt;/a&gt;, check it out!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/eTPexv6ZZMI" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-098</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-03-08T04:41:00Z</published>
		<updated>2010-03-19T09:48:45Z</updated>
		<title>Getting started with automated testing in Rails</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Fa8rY8lp3WI/getting-started-with-automated-testing-in-rails" />
		<id>tag:justinfrench.com,2010-03-08:083bed6ad50451eb341a307b6c00ee12/398aebf109113f8b1f2cec60876c9084</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;After my previous post &lt;a href="http://justinfrench.com//notebook/learn-how-to-test-your-code"&gt;learn to test your code&lt;/a&gt;, you might be wondering how to get started with automated testing.  Many books have been written on the topic, but I thought it might be interesting to share how &lt;em&gt;I&lt;/em&gt; got started.&lt;/p&gt;
	&lt;h3&gt;Testing in the Rails console&lt;/h3&gt;
	&lt;p&gt;One of my favorite things about Rails is the console (a Ruby irb console with the Rails environment loaded into it).  If you haven’t checked it out yet, go have a play.  You have access to ruby, your models, the database, helpers, ActiveSupport and much more. Here’s a quick example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ./script/console
Loading development environment (Rails 2.3.4)
&amp;gt;&amp;gt; "Hello World!".class
=&amp;gt; String
&amp;gt;&amp;gt; Post.count
=&amp;gt; 100
&amp;gt;&amp;gt; Post.published.last.title
=&amp;gt; "Hello world!"&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;I found I was playing around in console quite a lot when testing specific logic in my models, like validations.  It was far easier to copy-and-paste a few lines of ruby over and over instead of clicking around in my browser and entering data in all those form fields.&lt;/p&gt;
	&lt;p&gt;Let’s say you want to confirm that a new Post is valid when given an expected hash attributes (that the browser would usually post from a form being submitted):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Post.new.valid?
=&amp;gt; false
&amp;gt;&amp;gt; Post.new(:title =&amp;gt; "Hello", :body =&amp;gt; "World", :user_id =&amp;gt; "1").valid?
=&amp;gt; true&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;While the example may be trivial, that’s actually the point.  The tests I was performing in the console were exactly what I should have been automating — small, isolated, repeatable chunks of Ruby that confirm my understanding of what the code does by using it in the same way that I intended it to be used in my application.&lt;/p&gt;
	&lt;p&gt;In this case, I’m simply confirming that a new Post without attributes is invalid, and that a new Post with a title, body and user_id is valid.&lt;/p&gt;
	&lt;h3&gt;A quick introduction to unit tests&lt;/h3&gt;
	&lt;p&gt;For simplicity, I’m going to stick with test/unit and whatever ships with Rails in the standard testing framework provided in Rails 2.3.x, but you should be able to adapt these to rspec, Rails 3 or whatever you like.&lt;/p&gt;
	&lt;p&gt;If you used a generator to create your Post model in the first place, you should already have a file ready for your tests, located in RAILS_ROOT/test/unit/post_test.rb:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require 'test_helper'
class PostTest &amp;lt; ActiveSupport::TestCase
  # Replace this with your real tests.
  test "the truth" do
    assert true
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;You should be able to run your unit tests from the command line with this rake task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rake test:units&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;A bunch of noise is printed onto the screen, but what you’re looking for is something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Started
.
Finished in 0.12 seconds.
1 tests, 1 assertions, 0 failures, 0 errors&lt;/code&gt;&lt;/pre&gt; 
	&lt;p&gt;My friends, that dot is a passing test.  Let’s add a failing test, to check everything is working as expected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require 'test_helper'
class PostTest &amp;lt; ActiveSupport::TestCase
  test "the truth" do
    assert true
  end
  test "cats are the same as dogs" do
    assert_equal "cats", "dogs"
  end
end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Run the tests, we should see a failure:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Started
.F
Finished in 0.12 seconds.
2 tests, 2 assertions, 1 failures, 0 errors
1) Failure:
test_cats_are_the_same_as_dogs(PostTest)
[/test/unit/post_test.rb:9]:
&amp;lt;"cats"&amp;gt; expected but was
&amp;lt;"dogs"&amp;gt;.&lt;/code&gt;&lt;/pre&gt;
	&lt;h3&gt;Finally, automating our tests&lt;/h3&gt;
	&lt;p&gt;Let’s take a look at our console tests again:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt;&amp;gt; Post.new.valid?
=&amp;gt; false
&amp;gt;&amp;gt; Post.new(:title =&amp;gt; "Hello", :body =&amp;gt; "World", :user_id =&amp;gt; "1").valid?
=&amp;gt; true&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;The automated unit tests for these two are dead simple:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;test "should be invalid with no attributes" do
  assert !Post.new.valid?
end    
test "should be valid with a title, body and user_id" do
  assert Post.new(:title =&amp;gt; "Hello", :body =&amp;gt; "World", :user_id =&amp;gt; "1").valid?
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Run the tests, let’s see the dots!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Started
..
Finished in 0.12 seconds.
2 tests, 2 assertions, 0 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;    
	&lt;p&gt;Despite being utterly simple and trivial, those two tests document my understanding of what the software does (and should do going forward):&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;A Post with no attributes should be invalid.&lt;/li&gt;
		&lt;li&gt;A Post with a title, body and user_id should be valid.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;When they fail, either code isn’t doing what I expect, or the test is no longer valid.  I’ll adjust one of them accordingly.&lt;/p&gt;
	&lt;h3&gt;And that’s how I got started&lt;/h3&gt;
	&lt;p&gt;What about you? It’ll be tempting to open every model, look at every line of code and write tests for everything. That’s an incredibly ambitious plan, especially while you’re learning how to write good tests, how to structure them, etc.&lt;/p&gt;
	&lt;p&gt;Instead, start with one of your most business-critical controllers. Maybe it’s the signup process, or the home page, or the checkout. Have a look at how you’re &lt;em&gt;using&lt;/em&gt; your models, and replicate that usage with automated tests. Start with the golden path, then add more tests for the edge cases and irregular parts.&lt;/p&gt;
	&lt;p&gt;Another way to proceed is to start by writing a test to expose any bugs you come across. Write a failing test, fix the bug, watch the test pass, commit the changes.&lt;/p&gt;
	&lt;p&gt;I’ll cover both of these (and much more) soon.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Fa8rY8lp3WI" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/getting-started-with-automated-testing-in-rails</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-02-22T20:39:00Z</published>
		<updated>2010-02-22T21:09:26Z</updated>
		<title>Learn how to test your code</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/WNTzawDH_Ic/learn-how-to-test-your-code" />
		<id>tag:justinfrench.com,2010-02-22:083bed6ad50451eb341a307b6c00ee12/8f280a12e752aecefdcc2124450446c9</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;Recently, I was asked by someone new to Ruby and Rails what advice I had for them.  Other than “watch all the Railscasts”, I really only have one piece of advice:&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Learn how to test your software through automation.&lt;/strong&gt;&lt;/p&gt;
	&lt;p&gt;Learning how to write good tests for my code was the single most important step I made as a developer. I can’t more strongly emphasise this.&lt;/p&gt;
	&lt;p&gt;You’ll wrestle with it at first. You’ll be perplexed by the choices in testing frameworks and distracted by the subtle differences in terminology. You’ll be frustrated that you’re writing “twice as much code” for every feature. You’ll think you can hold the whole thing in your head and catch yourself making mistakes. Your boss will complain that things are taking too long.&lt;/p&gt;
	&lt;p&gt;Push through this shit. Sometimes the pay-off isn’t obvious for weeks or even months, but it’s always there.&lt;/p&gt;
	&lt;p&gt;Your tests are your safety net.  You’ll learn to lean on them, to trust them more than you trust yourself.  You’ll find you’re no longer terrified by huge changes to the code base, or sudden changes in direction.  You’ll see the occasional false alarm too (an “annoying” test that fails, but only exposed a bug in your testing approach).&lt;/p&gt;
	&lt;p&gt;Eventually (it’s only a matter of time), you’ll change something trivial and confidently commit to your version control system without running your tests. A few minutes later your co-workers (or even better, a continuous integration build server) will catch your mistake with a failing test.  Your trivial change just busted another part of the code you weren’t thinking about.&lt;/p&gt;
	&lt;p&gt;That code you just busted will be hidden somewhere in an obscure path through your shopping cart, and your test suite has just saved your company time, money and a loss of consumer confidence.&lt;/p&gt;
	&lt;p&gt;The light bulb goes on.  You get it, your boss probably gets it, but this is only the start of the journey.&lt;/p&gt;
	&lt;p&gt;Eventually you’ll forget that you used to spend &lt;em&gt;hours&lt;/em&gt; testing your code in a browser, and start complaining that your automated tests are taking &lt;em&gt;minutes&lt;/em&gt; to run! You’ll have intense debates with co-workers about what to test and how to test it properly. You’ll start writing the test &lt;em&gt;first&lt;/em&gt; to expose the bug or missing feature, then write the code required to pass the test.&lt;/p&gt;
	&lt;p&gt;This is the moment you realise you care more about your tests than you do about the code.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/WNTzawDH_Ic" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I was recently asked by someone new to Ruby and Rails what advice I had for them.  Other than “watch all the Railscasts”, I really only have one piece of advice.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/learn-how-to-test-your-code</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-02-21T19:40:23Z</published>
		<updated>2010-02-21T19:40:23Z</updated>
		<title>Moving to Feedburner, please update your feed URL</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/hh-L1ZuQPrM/moving-to-feedburner-please-update-your-feed-url" />
		<id>tag:justinfrench.com,2010-02-21:083bed6ad50451eb341a307b6c00ee12/fd6dfd79f1562f4482579610d075c090</id>
		<category term="This Site" />
		
		<content type="html">
	&lt;p&gt;The new feed URL is http://feeds.feedburner.com/justinfrench.  The old URLs should redirect for a while, but please update!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/hh-L1ZuQPrM" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/moving-to-feedburner-please-update-your-feed-url</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-02-03T12:01:08Z</published>
		<updated>2010-02-03T12:01:08Z</updated>
		<title>Nested has_many :through associations in Rails</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/r9e14U6ttZ0/nested-hasmany-through-associations-in-rails" />
		<id>tag:justinfrench.com,2010-02-03:083bed6ad50451eb341a307b6c00ee12/f6dca90d9dc73e5f6673d4794e6a74ca</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;It can’t be done.  You’re surprised, so am I.  I spent a few hours looking tonight, Rails (2.3.5 at the time of writing) doesn’t do this.  Even the rdoc says it:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;You can only use a :through query through a belongs_to or has_many association on the join model.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I have no idea about Rails 3 with the Arel changes to ActiveRecord, but here’s everything else I picked up along the way:&lt;/p&gt;
	&lt;h4&gt;The Bad News&lt;/h4&gt;
	&lt;ol&gt;
		&lt;li&gt;There’s an old &lt;a href="http://agilewebdevelopment.com/plugins/nested_has_many_through"&gt;plugin by Matt Wescott&lt;/a&gt; which supported this around Rails 2.1 (I think)&lt;/li&gt;
		&lt;li&gt;There’s a newer &lt;a href="http://github.com/ianwhite/nested_has_many_through"&gt;plugin by Ian White on GitHub&lt;/a&gt; based off Matt’s, which worked with Rails 2.1–2.2 it seems, but was busted by Rails 2.3.  There’s a &lt;a href="http://github.com/ianwhite/nested_has_many_through/tree/rails-2.3"&gt;branch&lt;/a&gt; for Rails 2.3, which it looks like they’re still working on (last commit December 2009).  I didn’t try it.&lt;/li&gt;
		&lt;li&gt;There’s an open ticket in Rails’ Lighthouse, everyone +1s the idea, no one has written a patch, Pratik marked it as incomplete, awaiting a patch from the community.  You should try to make that patch!&lt;/li&gt;
	&lt;/ol&gt;
	&lt;h4&gt;The Good News&lt;/h4&gt;
	&lt;ol&gt;
		&lt;li&gt;There is &lt;em&gt;something close&lt;/em&gt;, documented in &lt;a href="http://code.alexreisner.com/articles/has-many-through-habtm.html"&gt;Simulate Has Many Through HABTM&lt;/a&gt; by &lt;a href="http://code.alexreisner.com/"&gt;Alex Reisner&lt;/a&gt;.&lt;/li&gt;
		&lt;li&gt;It worked for me.&lt;/li&gt;
	&lt;/ol&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/r9e14U6ttZ0" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/nested-hasmany-through-associations-in-rails</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-02-01T21:51:00Z</published>
		<updated>2010-02-01T21:53:45Z</updated>
		<title>Google and IE6: Put the Champagne Away</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/QDk8tU3UqcQ/google-and-ie6-put-the-champagne-away" />
		<id>tag:justinfrench.com,2010-02-01:083bed6ad50451eb341a307b6c00ee12/3cc111675b4f557075d9da63ebb33c02</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;UXMag have just published a short post with the wonderfully luring and dramatic title &lt;a href="http://uxmag.com/short-news/google-kills-ie6"&gt;Google kills IE6&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Google is officially phasing out their support for IE6. This means we can all start working on more important things rather than debugging for old and quirky browsers. I think champagne is in order!&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I wish!  Let’s go look at Google’s &lt;a href="http://googleenterprise.blogspot.com/2010/01/modern-browsers-for-modern-applications.html"&gt;actual announcement&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;So to help ensure your business can use the latest, most advanced web apps, we encourage you to update your browsers as soon as possible.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;They’re dropping IE6 support for their &lt;em&gt;most advanced web apps&lt;/em&gt;, starting with Google Docs and Google Sites.  They aren’t dropping support across every Google product.  You can still go to google.com in IE6 and do a search.  &lt;/p&gt;
	&lt;p&gt;The decision to drop IE6 needs to be made by each business individually, based on strong business intelligence and data.  Google, of all companies, knows this.  &lt;/p&gt;
	&lt;p&gt;How many IE6 users—the ones that &lt;em&gt;won’t&lt;/em&gt; or &lt;em&gt;can’t&lt;/em&gt; upgrade to more advanced technologies—do you think actually &lt;em&gt;use&lt;/em&gt; Google Docs (an advanced web app) in any significant way?  I don’t know, but Google knows, which is why they dropped the support.&lt;/p&gt;
	&lt;p&gt;The upside to all this is that there may be a &lt;em&gt;few&lt;/em&gt; organisations heavily invested in Google that need to upgrade.  There may be a &lt;em&gt;few&lt;/em&gt; IT departments that finally get of their ass and upgrade their work stations.&lt;/p&gt;
	&lt;p&gt;This is progress, but it’s not magic.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/QDk8tU3UqcQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/google-and-ie6-put-the-champagne-away</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2010-01-28T22:12:00Z</published>
		<updated>2010-01-28T22:20:22Z</updated>
		<title>Testing Rails Plugin Config Preferences</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/rDoGjtS-1TQ/testing-rails-plugin-config-preferences" />
		<id>tag:justinfrench.com,2010-01-28:083bed6ad50451eb341a307b6c00ee12/ca5a0da98547bb1e7a50c49e2b9758a4</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;Time to start blogging again, I hope!  Most plugins and Ruby gems have configurable preferences, and usually they’re implemented as a Module or Class attribute, something like this:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;class AwesomeGem
  cattr_accessor :something
  @@something = true
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;In the case of a Rails plugin or gem, these are then modified with an initializer as Rails boots up:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;AwesomeGem.something = false&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Despite my best efforts to be opinionated, Formtastic has about 15 preferences today, and I can see another 10 or so on the horizon.  They all need to be tested.  For a while there, we had some pretty brittle tests that did this sort of stuff:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;describe AwesomeGem, "something preference" do
  describe "when true" do
    it "should..." do
      AwesomeGem.something = true
      # ...
    end
  end
  describe "when false" do
    it "should..." do
      AwesomeGem.something = false
      # ...
    end
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;The problem here is that we’ve changed AwesomeGem.something’s configuration from true (the default in the class) to false.  Any tests that assume the default preference will fail. Maybe. Who knows.  Depends on the order your tests run.&lt;/p&gt;
	&lt;p&gt;So we need to return the preference to it’s default state at the end of any tests that alter it:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;it "should..." do
  AwesomeGem.something = false
  # ...
  AwesomeGem.something = true
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;This is stupid and short-sighted.  Next week, someone changes the default value, and everything breaks.  What you need to do is capture the value before you change it, then return it to that state at the end of the test:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;it "should..." do
  old_value = AwesomeGem.something
  AwesomeGem.something = false
  # ...
  AwesomeGem.something = old_value
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;This works, but it’s shit code, especially if you’re repeating it in dozens of specs.  You can DRY it up a bit by moving it to before and after blocks, but it’s a heap of noisy, ugly code.  We can do better.  How about wrapping the above pattern up in a block that temporarily changes the configuration, like this:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;it "should..." do
  with_config :something, false do
    # ...
  end
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Here’s the implementation, throw it in your spec_helper.rb file:&lt;/p&gt;
 &lt;pre&gt;&lt;code&gt;def with_config(preference_name, temporary_value, &amp;block)
  old_value = AwesomeGem.send(preference_name)
  AwesomeGem.send(:"#{preference_name}=", temporary_value)
  yield
  AwesomeGem.send(:"#{preference_name}=", old_value)
end&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Enjoy!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/rDoGjtS-1TQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/testing-rails-plugin-config-preferences</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-12-02T21:06:00Z</published>
		<updated>2009-12-03T19:36:18Z</updated>
		<title>Formtastic 0.9.7 Released (Updated)</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/nT2dcLvkK0w/formtastic-095-released" />
		<id>tag:justinfrench.com,2009-12-02:083bed6ad50451eb341a307b6c00ee12/ad7adb148f31027d0a28cf2f315c47ac</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;Another bunch of really nice improvements and fixes have been added to the latest Formtastic gem:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;:selected option now works on all select, radio, check_box and date/time/datetime inputs, including multiple pre-selected values for check boxes and multi selects — huge thanks to grimen on this one!&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;Localized (I18n) titles now also works for inputs with the :for option set (nested forms). Closes #135.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;Added detection of group association method to use when grouping options for selects&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;You can now supply a custom builder on a form-by-form basis with the :builder option, rather than globally through configuration &lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;Using rspec_tag_matchers instead of rspec_hpricot_matchers (specs run faster!)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;./script/generator form can now be passed a—controller option to specify which controller to add the partial to (eg “admin/posts” instead of the default “posts”)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;del&gt;We now always call label_str_method (:humanize by default), previously human_attribute_name was also used in some case&lt;/del&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Thanks to everyone for their patches and support.&lt;/p&gt;
	&lt;p&gt;In more exciting news, the Button DSL branch is getting close, I’ll be pushing it up to Github as a remote branch and seeking feedback very soon, but I felt it was important to tidy up these bugs and keep the plugin moving forward in the meantime.&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Originally titled this post 0.9.5, but there was a tiny bug or two, so it’s now &lt;del&gt;0.9.6&lt;/del&gt; 0.9.7!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/nT2dcLvkK0w" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-095-released</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-11-16T21:26:00Z</published>
		<updated>2009-11-16T21:33:23Z</updated>
		<title>Formtastic 0.9.2 Released</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/25jkB7cTFbA/formtastic-092-released" />
		<id>tag:justinfrench.com,2009-11-16:083bed6ad50451eb341a307b6c00ee12/ba5fbdcf959140ef86ec29bb8d9204a3</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;I’ve just pushed the new Formtastic 0.9.2 gem up to &lt;a href="http://gemcutter.org/gems/formtastic"&gt;Gemcutter&lt;/a&gt; this morning on the train.  There’s a few API changes as we edge closer and closer 1.0, so I thought I’d do a quick post to document it all.&lt;/p&gt;
	&lt;h3&gt;Changes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;removed the fallback :save i18n key in commit_button and the erroneous deprecation warning — use the :update and :create keys instead&lt;/li&gt;
		&lt;li&gt;removed the generic method_name class from wrappers (f.input :title will no longer have a title class)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Additions&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;:radio inputs can now force one of the options to be pre-selected with the :selected option, just like :select inputs can&lt;/li&gt;
		&lt;li&gt;:select inputs now have a :group_by option to allow option grouping&lt;/li&gt;
		&lt;li&gt;a new inline error type :first (alongside :list and :sentence) was added, rendering only the first error found&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Fixes&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;fixed up some README examples&lt;/li&gt;
		&lt;li&gt;added the Formtastic::SemanticFormHelper.builder config to the example config in the generator&lt;/li&gt;
		&lt;li&gt;added some documentation and beefed up specs for the :selected option on a :select input&lt;/li&gt;
	&lt;/ul&gt;
	&lt;h3&gt;Under the hood&lt;/h3&gt;
	&lt;ul&gt;
		&lt;li&gt;made the gem post-install message a little more succinct&lt;/li&gt;
		&lt;li&gt;huge refactor and reorganization of the specs under the hood&lt;/li&gt;
		&lt;li&gt;minor refactor of the code base to make it a little easier to follow&lt;/li&gt;
		&lt;li&gt;deprecation errors are no longer silenced in the test suite&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Assuming no serious bugs pop up, the next stop is 1.0.  I’ve also started a Pledgie campaign, so if Formtastic is saving you or your clients a bit of time and money, please consider donating.&lt;/p&gt;
	&lt;p&gt;The &lt;a href="http://justinfrench.com/index.php?id=258"&gt;current campaign&lt;/a&gt; is for $555 by 5pm this Friday, in exchange for which I promise to work on Formtastic’s new button DSL for the entire weekend on RailsCamp here in Melbourne.&lt;/p&gt;
	&lt;p&gt;&lt;a href='http://www.pledgie.com/campaigns/2178?canvas=false'&gt;&lt;img alt='Click here to lend your support to: formtastic and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/2178.png?skin_name=chrome' border='0' /&gt;&lt;/a&gt;&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/25jkB7cTFbA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-092-released</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-11-08T05:28:00Z</published>
		<updated>2009-11-08T05:31:47Z</updated>
		<title>RailsCamp Project &amp; Pledgie Campaign</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/6j3bfwj9Lhk/railscamp-project-pledgie-campaign" />
		<id>tag:justinfrench.com,2009-11-08:083bed6ad50451eb341a307b6c00ee12/ac55eb2099a9a58b15a2198381dff19c</id>
		<category term="Ruby" />
		<category term="Plugins" />
		<content type="html">
	&lt;p&gt;There’s a &lt;a href="http://railscamps.com/#au_november_2009"&gt;RailsCamp coming up soon in Melbourne&lt;/a&gt;.  The whole idea of RailsCamp is to immerse yourself in some Ruby for a few days without distractions, and I’ve been looking around for a project to sink my teeth into.&lt;/p&gt;
	&lt;p&gt;One option I have is to put some work into Formtastic’s button DSL.  I personally haven’t found much need for it, but there’s been plenty of people asking.  The basic idea I pitched &lt;a href="http://groups.google.com.au/group/formtastic/msg/f2bc1136748ed4dd"&gt;a while back&lt;/a&gt; was something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;f.commit 
f.commit :as =&amp;gt; :button 
f.commit :as =&amp;gt; :link 
f.commit :as =&amp;gt; :link, :prefix =&amp;gt; "or" 
f.commit :as =&amp;gt; :image 
f.commit :as =&amp;gt; :image, :src =&amp;gt; "save.png"
f.cancel 
f.cancel :as =&amp;gt; :button 
f.cancel :as =&amp;gt; :link 
f.cancel :as =&amp;gt; :link, :prefix =&amp;gt; "or" 
f.cancel :as =&amp;gt; :image 
f.cancel :as =&amp;gt; :image, :src =&amp;gt; "cancel.png"&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;There’s literally hundreds of Ruby projects I’d love to hack on, and hundreds of features I could be working on that scratch my own itch, so maybe it’s time for an experiment:&lt;/p&gt;
	&lt;p&gt;There’s a &lt;a href="http://pledgie.com/campaigns/2178"&gt;Formtastic Pledgie campaign&lt;/a&gt; attached to the project on Github, currently sitting at $55.  If the campaign reaches $555 by the time I leave for the camp on Friday November 20, I’ll make sure I focus on this button DSL (and Formtastic in general) the entire weekend. The aim is to finish and release this feature.  If I’m done early, I’ll focus on documentation.&lt;/p&gt;
	&lt;p&gt;If we don’t hit the target (or go over), I’ll still make sure that your donations go directly towards improving Formtastic, of course!&lt;/p&gt;
	&lt;p&gt;So, please tweet this, blog this and spread the word however you can.  If you’re able to put some cash towards the project, even better.&lt;/p&gt;
	&lt;p&gt;&lt;a href='http://www.pledgie.com/campaigns/2178?canvas=false'&gt;&lt;img alt='Click here to lend your support to: formtastic and make a donation at www.pledgie.com !' src='http://www.pledgie.com/campaigns/2178.png?skin_name=chrome' border='0' /&gt;&lt;/a&gt;&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/6j3bfwj9Lhk" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/railscamp-project-pledgie-campaign</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-08-16T07:42:52Z</published>
		<updated>2009-08-16T07:42:52Z</updated>
		<title>Thoughtbot standardizes on Formtastic!</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/5VKJvioC5FM/thoughtbot-standardizes-on-formtastic" />
		<id>tag:justinfrench.com,2009-08-16:083bed6ad50451eb341a307b6c00ee12/81391489abf403cb30ae064630ed7d33</id>
		<category term="Rails" />
		<category term="Plugins" />
		<content type="html">
	&lt;p&gt;Thoughtbot on the recent updates to Suspenders (the Rails template they use in most of their projects):&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;We added formtastic (and the validation reflection plugin, which enables automatic “required field” labeling), which – after having spent 18 months or so talking about and never building the “perfect form builder” – we’ve decided to standardize on formtastic for all new projects.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;This is huge news for me.  We haven’t even reached what I consider a solid 1.0 candidate, and big firms like Thoughtbot are making &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt; part of their default toolbox, which means it’s going to be in a heap of Rails projects, and probably part of their workshop curriculum.&lt;/p&gt;
	&lt;p&gt;There’s an astonishing (for me) 700+ people watching the project on Github, 50+ forks, heaps of great feedback and positive buzz on Twitter.&lt;/p&gt;
	&lt;p&gt;Hopefully there’s a 0.9 gem in the next week or two (I know, feels like I’ve been saying that &lt;em&gt;forever&lt;/em&gt;), then we’re going to clean up some rough edges, remove the deprecated stuff and polish this thing up for a 1.0!&lt;/p&gt;
	&lt;p&gt;After that, I’ll introduce my &lt;em&gt;next&lt;/em&gt; Rails plugin for the view layer, which seems to have a few people excited already!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/5VKJvioC5FM" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/thoughtbot-standardizes-on-formtastic</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-07-14T11:53:00Z</published>
		<updated>2009-07-14T21:34:56Z</updated>
		<title>Around the Corner</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/BPKOZpVnBEU/around-the-corner" />
		<id>tag:justinfrench.com,2009-07-14:083bed6ad50451eb341a307b6c00ee12/aac6d0d5970036758c686f4d7b0ced1b</id>
		<category term="Web Industry" />
		<category term="CSS" />
		<content type="html">
	&lt;p&gt;I expect demos &lt;a href="http://www.satine.org/archives/2009/07/11/snow-stack-is-here/"&gt;like &lt;em&gt;Snow Stack&lt;/em&gt;&lt;/a&gt; to pop up more and more frequently as modern web browsers get the sort of CSS support we could only dream of a few years back.&lt;/p&gt;
	&lt;p&gt;It’s easy to dismiss this stuff because it’s Safari-only, but so many of these cutting edge CSS and HTML features will make it into modern browsers really soon, and we’ll have some amazing opportunities to provide web-native, indexable, linkable, resource-oriented, affordable, maintainable, incredibly rich web experiences with a few lines of CSS and Javascript.&lt;/p&gt;
	&lt;p&gt;No Flash, no plugins, no alternate or low-fi versions.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://westciv.com/style_master/blog/apples-navigation-bar-using-only-css"&gt;Graceful degredation&lt;/a&gt; (or progressive enhancement, depending on how you want to look at this stuff) will be a conversation we have with our clients far more often and we’ll spend a whole lot more time &lt;a href="http://forabeautifulweb.com/blog/about/walls_come_tumbling_down_presentation_slides_and_transcript/"&gt;designing in the browser&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;I can’t wait.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/BPKOZpVnBEU" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/around-the-corner</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-06-30T06:06:48Z</published>
		<updated>2009-06-30T06:06:48Z</updated>
		<title>Rails patch: Fixing human_name</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/8-kDBldqODA/rails-patch-fixing-humanname" />
		<id>tag:justinfrench.com,2009-06-30:083bed6ad50451eb341a307b6c00ee12/0ae3ec757b27d4fe94eb983d63104994</id>
		<category term="Rails" />
		<category term="Ruby" />
		<content type="html">
	&lt;p&gt;&lt;a href="http://github.com/rails/rails/commit/7d548f795d226f57278f8bdd36298c9552421053#comment_24577"&gt;This patch&lt;/a&gt; just got applied (finally!), which I’m happy about because I won’t have to hack around it in &lt;a href="http://github.com/justinfrench/formtastic"&gt;Formtastic&lt;/a&gt; any more.&lt;/p&gt;
	&lt;p&gt;Old: &lt;code&gt;SomeClass.human_name # =&amp;gt; "Someclass"&lt;/code&gt;&lt;br /&gt;
New: &lt;code&gt;SomeClass.human_name # =&amp;gt; "Some class"&lt;/code&gt;&lt;/p&gt;
	&lt;p&gt;Small steps, small steps.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/8-kDBldqODA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/rails-patch-fixing-humanname</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-02-17T23:01:00Z</published>
		<updated>2009-02-26T08:50:53Z</updated>
		<title>Git Aliases Rock</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/7qcQRA9As2k/git-aliases-rock" />
		<id>tag:justinfrench.com,2009-02-17:083bed6ad50451eb341a307b6c00ee12/d3aa5a5ee06506460ee2aa11b6ce062c</id>
		<category term="Git" />
		
		<content type="html">
	&lt;p&gt;Most of you Git users probably already know about &lt;a href="http://git.or.cz/gitwiki/Aliases"&gt;Git aliases&lt;/a&gt;.  Typically you add a few lines to ~/.gitconfig and you can alias &lt;code&gt;git co&lt;/code&gt; to &lt;code&gt;git checkout&lt;/code&gt;, etc:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[alias]
   co = checkout
   st = status
   ci = commit&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;But you can also use it to run shell commands by prefixing the alias with an exclamation mark (!), my first of which was aliasing &lt;code&gt;git df&lt;/code&gt; to &lt;code&gt;git diff | mate&lt;/code&gt; to pipe the diff into TextMate, which gives me pretty colors and a familiar environment:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;df = !git diff | mate&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Mostly I’m just lazy.  I’d prefer to type &lt;code&gt;git save mystashname&lt;/code&gt; instead of &lt;code&gt;git stash save mystashname&lt;/code&gt;, and &lt;code&gt;git pop&lt;/code&gt; instead of &lt;code&gt;git stash pop&lt;/code&gt;, because I find myself stashing a lot of stuff and like to give them proper names, etc etc.  It’s totally awesome that I can &lt;em&gt;make Git work for me&lt;/em&gt;.&lt;/p&gt;
	&lt;p&gt;The most crazy one I’ve been experimenting with so far wraps up a common pattern I have, which is…&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;switching back to the master branch from my generic “dev” branch&lt;/li&gt;
		&lt;li&gt;pulling from the remote&lt;/li&gt;
		&lt;li&gt;switching back to “dev”&lt;/li&gt;
		&lt;li&gt;rebasing “dev” against “master”&lt;/li&gt;
		&lt;li&gt;switching back to “master”&lt;/li&gt;
		&lt;li&gt;merging in the changes from “dev”&lt;/li&gt;
		&lt;li&gt;and finally running &lt;a href="http://git-wt-commit.rubyforge.org/#git-wtf"&gt;git wtf&lt;/a&gt; to show me what all my branches look like after the merge before I do a push.&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;I call this &lt;code&gt;git publish&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;publish = !git checkout master &amp;&amp; git pull &amp;&amp; git checkout dev &amp;&amp; git rebase master &amp;&amp; git checkout master &amp;&amp; git merge dev &amp;&amp; git wtf&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Get lazy! Go make Git and bash do the hard work for you!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/7qcQRA9As2k" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/git-aliases-rock</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-01-14T21:30:36Z</published>
		<updated>2009-01-14T21:30:36Z</updated>
		<title>Hello Web Developer, Goodbye Web Designer</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/-oklfF7sjjA/hello-web-developer-goodbye-web-designer" />
		<id>tag:justinfrench.com,2009-01-14:083bed6ad50451eb341a307b6c00ee12/b7579b164428d00b474b1a10f97bd39b</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;John Allsopp in &lt;a href="http://www.webdirections.org/blog/the-state-of-the-web-survey-results/"&gt;The State of the Web survey results&lt;/a&gt;&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;The day of the web developer has well and truly arrived, with a significant majority of respondents describing themselves as “developers” rather than designers, or a combination of the two. 95% or more or respondents use JavaScript, and over 90% of their sites are database driven.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;It’s about time!  I can’t remember the last time I built a static website, and more to the point, the average user doesn’t give a shit how your site magically works.  It’s just “on the internet”, and we, the web developers, are simply developing some more parts of the internet, like a property developer building some new apartments down the street.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/-oklfF7sjjA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/hello-web-developer-goodbye-web-designer</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2009-01-14T00:44:00Z</published>
		<updated>2009-01-14T00:57:07Z</updated>
		<title>Open-plan offices are making workers sick</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/U3Tl7th9Kb8/open-plan-offices-are-making-workers-sick" />
		<id>tag:justinfrench.com,2009-01-14:083bed6ad50451eb341a307b6c00ee12/fa00169659fd4e9537fe9d6fd41561a9</id>
		<category term="Productivity" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://www.joelonsoftware.com/items/2009/01/13.html"&gt;Joel&lt;/a&gt; and &lt;a href="http://danbenjamin.com/articles/2009/01/open-offices-reduce-productivity-and-increase-stress"&gt;Dan&lt;/a&gt; (and probably most of the internet by now) have jumped on &lt;a href="http://www.news.com.au/business/story/0,27753,24906913-5017672,00.html"&gt;this piece on news.com.au&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Australian scientists have reviewed a global pool of research into the effect of modern office design, concluding the switch to open-plan has led to lower productivity and higher worker stress.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;It’s fantastic to see some science and numbers to back this up, and I couldn’t agree more with the findings, but whoever funded this could’ve saved a few bucks by spending about 10 minutes in such an environment, which is exactly what management should do before asking their staff to do the same.&lt;/p&gt;
	&lt;p&gt;If money or space is really tight, &lt;em&gt;at least&lt;/em&gt; break it up into slightly smaller spaces.  Halving or quartering the noise and distractions by halving or quartering the space will have a huge, positive impact.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/U3Tl7th9Kb8" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/open-plan-offices-are-making-workers-sick</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-10-22T21:08:00Z</published>
		<updated>2008-10-22T21:08:33Z</updated>
		<title>Adding Empty Directories to a Git Repository</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/ZsLR3OhzQW8/adding-empty-directories-to-a-git-repository" />
		<id>tag:justinfrench.com,2008-10-22:083bed6ad50451eb341a307b6c00ee12/6dfe59aa4144f8bbfade8bb96cc9efaa</id>
		<category term="Bash" />
		<category term="Git" />
		<content type="html">
	&lt;p&gt;One of the biggest WTF moments when I started using Git for version control was that it refused to add (or even recognize) empty directories in the repository.&lt;/p&gt;
	&lt;p&gt;The &lt;a href="http://git.or.cz/gitwiki/GitFaq#head-1fbd4a018d45259c197b169e87dafce2a3c6b5f9"&gt;GitFaq&lt;/a&gt; sums it up just fine:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Currently the design of the git index (staging area) only permits files to be listed, and nobody competent enough to make the change to allow empty directories has cared enough about this situation to remedy it.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;The same FAQ also documents the “hack” that most people choose to work around this limitation:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;If you really need a directory to exist in checkouts you should create a file in it. .gitignore works well for this purpose; you can leave it empty, or fill in the names of files you expect to show up in the directory.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Fine, but I get a little sick of adding a bunch of .gitignore files to the many nested empty folders in a Rails project, or having to add the dirs myself when cloning something.&lt;/p&gt;
	&lt;p&gt;So here it is, a Bash one-liner which recursively adds an empty .gitignore file to every empty directory in the current working directory (with the exception of directories beginning with a dot, like .git for example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for i in $(find . -type d -regex ``./[^.].*'' -empty); do touch $i"/.gitignore"; done;&lt;code&gt;&lt;/pre&gt;
	&lt;p&gt;Add it into ~/.bashrc as an alias and save yourself precious minutes in every new project!&lt;/p&gt;
	&lt;p&gt;I’ve added it as a &lt;a href="http://gist.github.com/18780"&gt;gist&lt;/a&gt; on GitHub, so feel free to make improvements to it.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/ZsLR3OhzQW8" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/adding-empty-directories-to-a-git-repository</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-10-14T10:14:00Z</published>
		<updated>2008-10-14T10:25:06Z</updated>
		<title>The "Remember Me" Rant</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/V_Rjnp32IPI/the-remember-me-rant" />
		<id>tag:justinfrench.com,2008-10-14:083bed6ad50451eb341a307b6c00ee12/828837e2d225c702f14bc5fd5fe37607</id>
		<category term="Usability" />
		
		<content type="html">
	&lt;p&gt;The “remember me” functionality, present in most web applications and web services is awesome.  If you want to be remembered (and avoid logging in next time), check the box during the login process and it’s taken care of with a cookie.  Next time you return, it’s like you never left.  Awesome.&lt;/p&gt;
	&lt;p&gt;But what’s up with “remember me for 2 weeks”, as found in &lt;a href="https://secure.delicious.com/login"&gt;Delicious&lt;/a&gt;, for example.  I don’t get it.  It helps you out for two weeks like a champion, then just when things are going so well, it screws everything up by dropping the ball.  Thanks for nothin’.&lt;/p&gt;
	&lt;p&gt;It’s broken because it feels &lt;em&gt;less&lt;/em&gt; helpful than forcing me to login each visit — at least regular logins would help me commit the login details to memory.&lt;/p&gt;
	&lt;p&gt;If there’s a legit reason to expire the cookie after some period of time (I’m not convinced, but I’m keen to hear why), perhaps an improvement would be to &lt;em&gt;continue&lt;/em&gt; remembering me for a period of 2 weeks, resetting the expiration date on the cookie each time I return to the site.&lt;/p&gt;
	&lt;p&gt;That feels like a pretty good experience to me.&lt;/p&gt;
	&lt;p&gt;Perhaps this is what the original “trail blazers” of this pattern had in mind, and somewhere along the way it got dumbed down and recycled into this awkward anti-pattern.&lt;/p&gt;
	&lt;p&gt;Optional listening material: &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=277066083&amp;s=143460"&gt;It’s the innocent smiles you get at the start of a relationship before you fuck everything up&lt;/a&gt; by Aussie band &lt;a href="http://www.wearemappingyourdreams.com/"&gt;Laura&lt;/a&gt;&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/V_Rjnp32IPI" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/the-remember-me-rant</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-09-11T01:27:35Z</published>
		<updated>2008-09-11T01:27:35Z</updated>
		<title>The Commonalities</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/rM59J94v03U/the-commonalities" />
		<id>tag:justinfrench.com,2008-09-11:083bed6ad50451eb341a307b6c00ee12/aec660d454f6f2bd046580fc58f527d5</id>
		<category term="Usability" />
		
		<content type="html">
	&lt;p&gt;I’ve been doing a huge purge of my feeds lately, but &lt;a href="http://www.cooper.com/journal/"&gt;The Cooper Journal&lt;/a&gt; will be staying put!  I particularly enjoyed &lt;a href="http://www.cooper.com/journal/2008/09/the_homer.html"&gt;The parable of The Homer&lt;/a&gt;, posted a few minutes ago: &lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;The moral is of course that designing for almost any single individual runs a huge risk of building a product around personal idiosyncrasies—the things that are different about that person, which is a lot different than designing for personas or user archetypes where the goal is to make decisions focused on the commonalities between members of the intended audience.&lt;/p&gt;
	&lt;/blockquote&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/rM59J94v03U" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/the-commonalities</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-07-01T03:31:00Z</published>
		<updated>2008-07-01T03:54:20Z</updated>
		<title>Absurd Time Extensions</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/he6pRuWkE9s/absurd-time-extensions" />
		<id>tag:justinfrench.com,2008-07-01:083bed6ad50451eb341a307b6c00ee12/03fdf63179decb1576e7ed4ec981b87b</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://blog.whoisjohnbarton.com/"&gt;John Barton&lt;/a&gt; just made my afternoon 10% more awesome with his &lt;a href="http://github.com/joho/absurd-time-extensions/tree/master/time_ext.rb"&gt;Absurd Time Extensions&lt;/a&gt; on Github:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
class Time
  attr_accessor :white_rapper
  def stop!
    if white_rapper
      "collaborate and listen"
    else
      "Hammertime!"
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; My contribution, &lt;a href="http://github.com/justinfrench/absurd-time-extensions/commit/3029267cae50df863ffc273bfe3e44c3e297ec29"&gt;Time.now.coffee?&lt;/a&gt; with a 3pm cut-off.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/he6pRuWkE9s" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/absurd-time-extensions</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-06-27T02:12:00Z</published>
		<updated>2008-07-20T19:30:40Z</updated>
		<title>Git Commits That Need to be Pushed, Part 2</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/3kx6f5GH1Sw/git-commits-that-need-to-be-pushed-part-2" />
		<id>tag:justinfrench.com,2008-06-27:083bed6ad50451eb341a307b6c00ee12/a86a1f134c9a4ed7cc935b1ab7f11f95</id>
		<category term="Git" />
		
		<content type="html">
	&lt;p&gt;Update: &lt;code&gt;FETCH_HEAD&lt;/code&gt; doesn’t really work the way I hoped, so I’ve reverted to a modified version of &lt;a href="http://justinfrench.com/index.php?id=240"&gt;my previous solution&lt;/a&gt;.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/3kx6f5GH1Sw" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/git-commits-that-need-to-be-pushed-part-2</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-06-22T23:57:01Z</published>
		<updated>2008-06-22T23:57:01Z</updated>
		<title>Hardware and Software</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/CBe1fzFURh8/hardware-and-software" />
		<id>tag:justinfrench.com,2008-06-22:083bed6ad50451eb341a307b6c00ee12/0cc05a11b910dedf54669a3878fa28c0</id>
		<category term="Me" />
		<category term="Apple" />
		<content type="html">
	&lt;p&gt;Last week my hard drive started making those wonderful clicking noises, and I started seeing way too many “spinning beach balls of death”.  A day later, the system wouldn’t start up, so that was that.  Dead hard drive.&lt;/p&gt;
	&lt;p&gt;I grabbed one of the ‘emergency’ laptops from work (a black MacBook), plugged in the TimeMachine back-up, and was up-and-running on the new system pretty quick.&lt;/p&gt;
	&lt;p&gt;Physically, this is a really different laptop than my MacBook Pro or the Powerbook I had before it – the keyboard is just plain weird, the lid latches differently, the screen is glossy, the ports are all in different places, the resolution of the screen is different, the dimensions are smaller, it’s plastic rather than aluminum, etc.&lt;/p&gt;
	&lt;p&gt;Despite this, I felt comfortable on it almost instantly.  It was &lt;em&gt;my computer&lt;/em&gt; so fast, adding weight to something I’ve always suspected was true – the software and settings installed my Mac is what makes me feel so at home, not really the hardware or even Mac OS X.  I can jump on a friend’s Mac and feel almost as lost as I would jumping on a PC.&lt;/p&gt;
	&lt;p&gt;The system you interact with every day is the one you’re going to feel most comfortable on.  Instinct takes over from logic and familiar UIs are forgiven their inadequacies.&lt;/p&gt;
	&lt;p&gt;When people say “I love Macs”, what they really mean is “I love &lt;em&gt;my&lt;/em&gt; Mac”, and when they say that, they really mean “I love what I’ve done with my Mac”.&lt;/p&gt;
	&lt;p&gt;This is also the reason why I occasionally hear the words “I love my PC”, as strange as it sounds to the rest of us.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/CBe1fzFURh8" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/hardware-and-software</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-29T23:45:00Z</published>
		<updated>2008-05-30T00:45:43Z</updated>
		<title>Formtastic Sneaky Preview</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/WkBJBPec5Qk/formtastic-sneaky-preview" />
		<id>tag:justinfrench.com,2008-05-29:083bed6ad50451eb341a307b6c00ee12/d090850269842b1f23d0faacdee7c0d2</id>
		<category term="Rails" />
		<category term="Git" />
		<content type="html">
	&lt;p&gt;Last night at Melbourne Ruby I gave a quick presentation of the &lt;a href="http://github.com/justinfrench/formtastic/"&gt;Formtastic Rails FormBuilder plugin&lt;/a&gt; I’ve been working on, and thought it was about time I announced it here also.&lt;/p&gt;
	&lt;p&gt;The &lt;a href="http://github.com/justinfrench/formtastic/tree/master#readme"&gt;README&lt;/a&gt; serves as a pretty good introduction to what I’m trying to do, so please just go and read that instead.&lt;/p&gt;
	&lt;p&gt;If you’re too lazy for that, it’s a sweet DSL for authoring forms, a FormBuilder that goes to great lengths to provide semantically rich markup with plenty of hooks for stylesheet authors, and a (work-in-progress) set of stylesheets that make that mark-up look great For Free™.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://rhnh.net"&gt;Xavier Shay&lt;/a&gt; has been bold enough to start using it in the wonderful &lt;a href="http://enkiblog.com"&gt;Enki&lt;/a&gt;, and I’m using it on a few small projects for friends, so I hope we might be at a 1.0-ish stable and useful release in a month or two.&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; If you haven’t yet discovered the bliss of Github/Git combo, please sign-up for an account, start following me, start watching Formtastic, start forking some things and it will soon become crystal clear just how well the Github team have nailed the &lt;em&gt;social&lt;/em&gt; side of open source software development, and how much sense distributed version control makes.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/WkBJBPec5Qk" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/formtastic-sneaky-preview</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-27T12:44:00Z</published>
		<updated>2008-07-20T19:33:00Z</updated>
		<title>Git Commits That Need to be Pushed</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/FTNYWi0fUZQ/git-commits-that-need-to-be-pushed" />
		<id>tag:justinfrench.com,2008-05-27:083bed6ad50451eb341a307b6c00ee12/6781736202562fa38b2942dd9f52e86d</id>
		<category term="Steal My Code" />
		
		<content type="html">
	&lt;p&gt;I constantly find myself wondering what the difference is between what I’ve committed to my local Git repository, and what’s been pushed up to Github.  Here’s one way, I’m sure there’s others:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
git cherry -v origin/master
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Or, how about a bash alias?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
alias push?='git cherry -v origin/master'
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Winner.&lt;/p&gt;
	&lt;p&gt;&lt;em&gt;Updated 21 July 2008 to use &lt;code&gt;origin/master&lt;/code&gt; instead of just &lt;code&gt;origin&lt;/code&gt;, which works far more reliably in my various projects, with thanks to Stefan Naewe who emailed me with this suggestion.&lt;/em&gt;&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/FTNYWi0fUZQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/git-commits-that-need-to-be-pushed</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-25T23:15:00Z</published>
		<updated>2008-05-25T23:16:27Z</updated>
		<title>Rails, Git, Github, etc</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/t8Zc25KJlmE/rails-git-github-etc" />
		<id>tag:justinfrench.com,2008-05-25:083bed6ad50451eb341a307b6c00ee12/1bd03800abf2734408a3f2b49857ce71</id>
		<category term="Git" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;A little collection of things I’ve found useful as I dig deeper into Git, dealing with forks, branches, pull requests, patches, etc.  There hasn’t been one glorious moment where “the penny drops” and it all makes sense to me… Instead, it’s been dropping again and again as I absorb more about people’s workflows and usage patterns.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://rails.lighthouseapp.com/projects/8994/sending-patches"&gt;Contributing to Rails&lt;/a&gt; in the Rails Lighthouse system&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/everyday.html"&gt;Everyday Git with 20 Commands&lt;/a&gt; &lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/"&gt;Git Manual Page&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://b.lesseverything.com/2008/3/25/got-git-howto-git-and-github"&gt;Got Git? How to Git and github&lt;/a&gt; by Steven Bristol&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://tomayko.com/writings/the-thing-about-git"&gt;The Thing About Git&lt;/a&gt; by Ryan Tomayko&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://drnicwilliams.com/2008/02/03/using-git-within-a-team/" title="forking around"&gt;Using Git within a project&lt;/a&gt; by Dr Nic&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://cheat.errtheblog.com/s/git"&gt;Git Cheat Sheet&lt;/a&gt; by Err Free&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://git.or.cz/course/svn.html"&gt;Git – SVN Crash Course&lt;/a&gt; by Petr Baudis&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;I’ll add more as I find them, feel free to email me&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/t8Zc25KJlmE" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/rails-git-github-etc</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-24T01:15:00Z</published>
		<updated>2008-05-24T01:16:39Z</updated>
		<title>MS Walk 2008 – Give Me All Your Money</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/x4SvSg91Tq8/ms-walk-2008--give-me-all-your-money" />
		<id>tag:justinfrench.com,2008-05-24:083bed6ad50451eb341a307b6c00ee12/45dd31de14cdbeee16f80f865c046d45</id>
		<category term="Friends" />
		<category term="Fun" />
		<content type="html">
	&lt;p&gt;Every year my wife &lt;em&gt;forces&lt;/em&gt; me walk around &lt;a href="http://maps.google.com.au/maps?f=q&amp;hl=en&amp;geocode=&amp;q=albert+park+lake&amp;sll=-37.786546,145.257051&amp;sspn=0.010717,0.017767&amp;ie=UTF8&amp;z=15&amp;iwloc=addr"&gt;Albert Park Lake&lt;/a&gt; for the MS Walk, and every year I complain about getting up early on a Sunday, later realizing it’s quite fun, and 5km is really not that far at all, and 10:30am isn’t actually that early.&lt;/p&gt;
	&lt;p&gt;They have a sausage sizzle, you can see dogs chasing ducks (or vice-versa) and even though you’re paying $22 for the privilege of walking around a lake which is otherwise public property, it’s for a good cause.&lt;/p&gt;
	&lt;p&gt;This year Kate’s putting a team together, so if you’re in Melbourne, you can &lt;a href="http://melbourne.mswalk.org.au/?First+National"&gt;join us on Sunday June 1st&lt;/a&gt; if you like.&lt;/p&gt;
	&lt;p&gt;Alternatively, they’ve added the extra guilt trip of an (optional) fund raising thing where I can attempt to squeeze money out of all my friends who are too smart to get out of bed on a weekend or don’t think I can actually walk 5kms without a coffee break.  &lt;a href="https://melbourne.mswalk.org.au/donate.html?justinfrench"&gt;You may give me &lt;em&gt;all your money&lt;/em&gt; here&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;Please don’t feel obligated at all, I’m just having a bit of fun!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/x4SvSg91Tq8" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/ms-walk-2008--give-me-all-your-money</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-21T23:09:00Z</published>
		<updated>2008-05-21T23:09:36Z</updated>
		<title>Coffee Chicken</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/DTtGTyUbwFU/coffee-chicken" />
		<id>tag:justinfrench.com,2008-05-21:083bed6ad50451eb341a307b6c00ee12/df72034708498242791ffe833cc9a459</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;In a small office of people eager for their mid-morning coffee, participants must weigh up their strong desire for caffeine against the burden of being the first to break, becoming the Coffee Chicken.&lt;/p&gt;
	&lt;p&gt;The Coffee Chicken must take complex orders, deal with handfuls of loose change, return with trays of coffee and deal with never ending complaints &amp; commentary from those who showed greater strength of character.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/DTtGTyUbwFU" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/coffee-chicken</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-20T22:22:34Z</published>
		<updated>2008-05-20T22:22:34Z</updated>
		<title>Geoffrey Grosenbach on mod_rails</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/K_SQSc8kHnM/geoffrey-grosenbach-on-modrails" />
		<id>tag:justinfrench.com,2008-05-20:083bed6ad50451eb341a307b6c00ee12/7172e3f9ba1b37cfc6fb5270f6d4d485</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;This is a &lt;a href="http://nubyonrails.com/articles/ask-your-doctor-about-mod_rails"&gt;nice little write-up&lt;/a&gt; worth the read.  I particularly like the idea of automatically restarting the application (in development) when files inside &lt;code&gt;vendor&lt;/code&gt; are edited, which is my number one gripe when developing or maintaining plugins or other libraries that are only loaded once by Rails.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/K_SQSc8kHnM" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/geoffrey-grosenbach-on-modrails</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-12T06:21:58Z</published>
		<updated>2008-05-12T06:21:58Z</updated>
		<title>Crunch Crunch</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/wDn4vldUDfQ/crunch-crunch" />
		<id>tag:justinfrench.com,2008-05-12:083bed6ad50451eb341a307b6c00ee12/2962d3aaefbbcafb1d2e43494ef84800</id>
		<category term="Fun" />
		
		<content type="html">
	&lt;p&gt;&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/KYOGbo0A0cE&amp;hl=en"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/KYOGbo0A0cE&amp;hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
	&lt;p&gt;Not code at all. Meg &amp; Gus, going to town on some dog biscuits.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/wDn4vldUDfQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/crunch-crunch</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-06T23:01:22Z</published>
		<updated>2008-05-06T23:01:22Z</updated>
		<title>iPhone with Vodafone in Australia</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/AT-r2EgUK4Y/iphone-with-vodafone-in-australia" />
		<id>tag:justinfrench.com,2008-05-06:083bed6ad50451eb341a307b6c00ee12/abedef6b2aa1cb5e76bf34897c8c77c6</id>
		<category term="Apple" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://www.vodafone.com/start/media_relations/news/group_press_releases/2007/vodafone_to_offer0.html"&gt;Good stuff&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Vodafone today announced it has signed an agreement with Apple to sell the iPhone in ten of its markets around the globe. Later this year, Vodafone customers in Australia, the Czech Republic, Egypt, Greece, Italy, India, Portugal, New Zealand, South Africa and Turkey will be able to purchase the iPhone for use on the Vodafone network.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Via &lt;a href="http://daringfireball.net"&gt;Daring Fireball&lt;/a&gt;.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/AT-r2EgUK4Y" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/iphone-with-vodafone-in-australia</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-05-04T23:31:00Z</published>
		<updated>2008-05-05T05:55:28Z</updated>
		<title>VCS Agnostic Bash Functions</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/dTU0-MKE6Vg/vcs-agnostic-bash-functions" />
		<id>tag:justinfrench.com,2008-05-04:083bed6ad50451eb341a307b6c00ee12/fbb7255d8ff74e54bd9e34b3501470b2</id>
		<category term="Productivity" />
		<category term="Steal My Code" />
		<content type="html">
	&lt;p&gt;For the last 2 years, I’ve had a bash alias &lt;code&gt;st&lt;/code&gt; which mapped to &lt;code&gt;svn status&lt;/code&gt;.  Understandably, I’ve built up significant muscle memory here, and every time I want to know the status of a project, that’s what I type.&lt;/p&gt;
	&lt;p&gt;Then Git came along and ruined everything (in the best possible way).  Typing &lt;code&gt;st&lt;/code&gt; just resulted in SVN errors.  I made a new alias &lt;code&gt;gst&lt;/code&gt;, but my fingers just want to type &lt;code&gt;st&lt;/code&gt;.&lt;/p&gt;
	&lt;p&gt;Problem solved with a tiny bash function:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 function st() {
   git branch &amp;&amp;gt;/dev/null
   if [ $? -eq 0 ]; then
     git status;
   else
     svn status;
   fi
 }
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;I’m certain this can be improved, but it’s a great start.  &lt;a href="http://rhnh.net"&gt;Xavier&lt;/a&gt; chimed in with the obvious next step:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 function ci() {
   git branch &amp;&amp;gt;/dev/null
   if [ $? -eq 0 ]; then
     git commit -m;
   else
     svn ci -m;
   fi
 }
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;And pretty soon I’ll have a whole swag of them replacing my old bash aliases with functions.&lt;/p&gt;
	&lt;p&gt;Anyone know a better way to test for Git?  What about DRYing up the check so that I can re-use it in each function?  Please email me, I’m such a bash newb.&lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Ben Birnbaum writes in again with &lt;a href="http://pastie.caboo.se/191562"&gt;a simplification and clean-up&lt;/a&gt; which seems to work great.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/dTU0-MKE6Vg" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/vcs-agnostic-bash-functions</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-29T13:27:00Z</published>
		<updated>2010-10-19T10:00:30Z</updated>
		<title>A custom Rake task to reset and seed your database</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/pCtJguhpBZg/a-custom-rake-task-to-reset-and-seed-your-database" />
		<id>tag:justinfrench.com,2008-04-29:083bed6ad50451eb341a307b6c00ee12/bcab8d477c69f252fde9aece18dbb9df</id>
		<category term="Steal My Code" />
		<category term="Ruby" />
		<content type="html">
	&lt;p&gt;No matter how obvious I think this stuff is now, there was a point when it wasn’t, so I’m trying to share more.  Here’s something I do &lt;em&gt;a lot&lt;/em&gt; during the initial development process of a Rails application:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;drop the current database&lt;/li&gt;
		&lt;li&gt;re-create it&lt;/li&gt;
		&lt;li&gt;run all the migrations&lt;/li&gt;
		&lt;li&gt;load in some sample data from the fixtures (or elsewhere)&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;The good news is that Rails provides a Rake task for each of these (run &lt;code&gt;$ rake --tasks | grep 'db'&lt;/code&gt; to see plenty more), so if you &lt;em&gt;really&lt;/em&gt; like typing you can just run these four commands:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;&lt;code&gt;rake db:drop&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rake db:create&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rake db:migrate&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;rake db:fixtures:load&lt;/code&gt;&lt;/li&gt;
	&lt;/ol&gt;
	&lt;p&gt;No way, typing is for suckers.  What you (should) want to do is encapsulate this thing you want to do over and over as a new custom Rake task.  Let’s go with &lt;code&gt;rake db:seed&lt;/code&gt;.&lt;/p&gt;
	&lt;p&gt;Create a new file &lt;code&gt;application.rake&lt;/code&gt; (or &lt;code&gt;db.rake&lt;/code&gt;, whatever) in &lt;code&gt;RAILS_ROOT/lib/tasks&lt;/code&gt; with the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
namespace :db do
  desc "Drop, create, migrate then seed the database"
  task :seed =&amp;gt; :environment do
    Rake::Task['db:drop'].invoke
    Rake::Task['db:create'].invoke
    Rake::Task['db:migrate'].invoke
    Rake::Task['db:fixtures:load'].invoke
  end
end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Give it a try, I’ll wait. &lt;strong&gt;Warning:&lt;/strong&gt; This will totally hose your database!  &lt;/p&gt;
	&lt;p&gt;And we can clean this up too.  &lt;code&gt;task :seed =&amp;gt; :environment&lt;/code&gt; is telling rake to run the ‘environment’ task (it loads the Rails environment) before running the rest of the task.  We can actually pass in s set of tasks as an Array:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
namespace :db do
  desc "Drop, create, migrate then seed the database"
  task :seed =&amp;gt; [
    'environment', 
    'db:drop', 
    'db:create', 
    'db:migrate', 
    'db:fixtures:load'
  ]
end
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Finally, I’ll sleep better tonight if you make sure this task can only run in the development environment (ensuring you can’t accidentally hose your production data), so let’s add another task ‘development_environment_only’ and include it in the task list:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
namespace :db do
  desc "Raise an error unless the RAILS_ENV is development"
  task :development_environment_only do
    raise "Hey, development only you monkey!" unless RAILS_ENV == 'development'
  end
  desc "Drop, create, migrate then seed the development database"
  task :seed =&amp;gt; [
    'environment', 
    'db:development_environment_only', 
    'db:drop', 
    'db:create', 
    'db:migrate', 
    'db:fixtures:load'
    ]
  end
end
&lt;/code&gt;&lt;/pre&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/pCtJguhpBZg" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/a-custom-rake-task-to-reset-and-seed-your-database</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-29T11:19:00Z</published>
		<updated>2008-04-29T21:30:11Z</updated>
		<title>Stupid Bash Tricks: Copy The Working Directory</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/aogsjz7F0Aw/stupid-bash-tricks-copy-the-working-directory" />
		<id>tag:justinfrench.com,2008-04-29:083bed6ad50451eb341a307b6c00ee12/f898a22733cfea73f484b88971fc1cf3</id>
		<category term="OS X" />
		
		<content type="html">
	&lt;h3&gt;The Problem&lt;/h3&gt;
	&lt;p&gt;I have a Terminal window open, I’m doing stuff and I want to open another Terminal window or tab to the same current working directory.&lt;/p&gt;
	&lt;h3&gt;A Possible Solution&lt;/h3&gt;
	&lt;p&gt;I recently added this to my &lt;code&gt;~/.bash_login&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
alias cwd='pwd | pbcopy'
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;This might be stating the obvious, but &lt;code&gt;pwd&lt;/code&gt; outputs the current working directory, and we pipe that into &lt;code&gt;pbcopy&lt;/code&gt; which copies that output to the paste board.  I choose &lt;code&gt;cwd&lt;/code&gt; (Copy Working Directory) as the alias, your mileage may vary.&lt;/p&gt;
	&lt;p&gt;It’s still a bit fiddly, but better than grabbing the mouse to copy the current working directory:&lt;/p&gt;
	&lt;ol&gt;
		&lt;li&gt;type &lt;code&gt;cwd&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;type Command-T (new tab in Terminal.app)&lt;/li&gt;
		&lt;li&gt;type &lt;code&gt;cd &lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;type Command-V (Paste)&lt;/li&gt;
	&lt;/ol&gt;
	&lt;h3&gt;Can you better?&lt;/h3&gt;
	&lt;p&gt;Ideally I’d like to get this down to one key-stroke.  Automator’s “Watch Me Do” recordable action was looking promising, but it runs horribly slow.  Applescript maybe?  &lt;a href="http://justinfrench.com//?s=contact"&gt;Email me&lt;/a&gt; or go nuts in the comments! &lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Update 1:&lt;/strong&gt;&lt;/p&gt;
	&lt;p&gt;Benjamin Birnbaum writes in with &lt;a href="http://pastie.caboo.se/188640"&gt;this bash function&lt;/a&gt;.  There’s still some lag (AppleScript lag I guess) but I’m suitably impressed!  &lt;/p&gt;
	&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt;&lt;/p&gt;
	&lt;p&gt;Chap Lovejoy writes in with this AppleScript which I’m yet to try out:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
tell application "Terminal"
  activate
  set wnd to the front window
  set tb to the selected tab of wnd
  -- We don't want to clobber any running process
  if not busy of tb then
    -- Clear the current command line
    tell application "System Events"
      keystroke "a" using control down
      keystroke "k" using control down
    end tell
    do script "pwd | pbcopy" in tb
    -- The make comamnd in Terminal appears to be
    -- broken so generate the keystroke as a workaround
    tell application "System Events"
      keystroke "t" using command down
    end tell
    do script "cd \"`pbpaste`\"" in the selected tab of wnd
  end if
end tell
&lt;/code&gt;&lt;/pre&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/aogsjz7F0Aw" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/stupid-bash-tricks-copy-the-working-directory</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-28T07:40:49Z</published>
		<updated>2008-04-28T07:40:49Z</updated>
		<title>A screen that ships without a mouse ships broken</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/EgSVgRXRuo8/a-screen-that-ships-without-a-mouse-ships-broken" />
		<id>tag:justinfrench.com,2008-04-28:083bed6ad50451eb341a307b6c00ee12/a766d594c887b691c6a3e6674fb99954</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;Clay Shirky has an amazing post/transcript &lt;a href="http://www.herecomeseverybody.org/2008/04/looking-for-the-mouse.html"&gt;Gin, Television, and Social Surplus&lt;/a&gt; of which I could quote pretty much the entire thing, but I’ll just urge you to find some time to read it instead.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/EgSVgRXRuo8" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/a-screen-that-ships-without-a-mouse-ships-broken</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-23T23:55:35Z</published>
		<updated>2008-04-23T23:55:35Z</updated>
		<title>Timeframe Calendar Picker</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/sMvKMkarRsQ/timeframe-calendar-picker" />
		<id>tag:justinfrench.com,2008-04-23:083bed6ad50451eb341a307b6c00ee12/98277893b8a737b2caeb7f7bd69a0fea</id>
		<category term="CSS" />
		<category term="JavaScript" />
		<content type="html">
	&lt;p&gt;Mental note: &lt;a href="http://stephencelis.com/projects/timeframe"&gt;Start here&lt;/a&gt; next time I need to implement a calendar picker UI!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/sMvKMkarRsQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/timeframe-calendar-picker</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-17T03:17:00Z</published>
		<updated>2008-04-17T03:22:17Z</updated>
		<title>Great Review of RedBubble</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/4OR-utt0h-w/great-review-of-redbubble" />
		<id>tag:justinfrench.com,2008-04-17:083bed6ad50451eb341a307b6c00ee12/d5e70f9792fe172649c97abe06d88dbc</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;Zoe Marlowe &lt;a href="http://www.devlounge.net/articles/upload-and-manage-your-images-online-for-free"&gt;has a warm review&lt;/a&gt; of &lt;a href="http://www.redbubble.com"&gt;RedBubble&lt;/a&gt; alongside Flickr and others on Devlounge:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;What’s great and amazing about Redbubble is that it is a veritable “United Nations” of photographers, fine artists and writers. Everyone there has the ability to create their own personal page or “gallery” full of their work, whether it is art or prose, you have a place to do your thing for absolutely free. What else is fantastic about the “Bubble” is that you have the opportunity to actually sell your work, seriously! You can choose several different format options for your art and sell it as prints, greeting cards, or posters, whatever you want! Heck, you can even design and sell T-shirts of your art work. How cool is that?&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;And this finalé:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;I absolutely can’t say enough about this site, it’s really a ‘home away from home’ inside my computer! This online cybercafé, art gallery and community gets the absolute most rousing, foot stomping, Bic-flicking standing ovation from me ever!&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I tend to get weighed down day-to-day by all the things I see on the site that we haven’t done, or that we did in a furious hurry, or that we’re still trying to find time to do, and this serves as a wonderful reminder of what we &lt;em&gt;have&lt;/em&gt; done.  Thanks Zoe!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/4OR-utt0h-w" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/great-review-of-redbubble</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-04-14T20:31:42Z</published>
		<updated>2008-04-14T20:31:42Z</updated>
		<title>Signal vs. Noise: Urgency is Poisonous</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Ji2ESuLo0DA/signal-vs-noise-urgency-is-poisonous" />
		<id>tag:justinfrench.com,2008-04-14:083bed6ad50451eb341a307b6c00ee12/f23b47f8953d05f3d54b8868cbbaa222</id>
		<category term="Productivity" />
		
		<content type="html">
	&lt;p&gt;Jason Fried &lt;a href="http://www.37signals.com/svn/posts/966-urgency-is-poisonous"&gt;nails it&lt;/a&gt; once again:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;One thing I’ve come to realize is that urgency is overrated. In fact, I’ve come to believe urgency is poisonous. Urgency may get things done a few days sooner, but what does it cost in morale? Few things burn morale like urgency. Urgency is acidic.&lt;/p&gt;
	&lt;/blockquote&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Ji2ESuLo0DA" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/signal-vs-noise-urgency-is-poisonous</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-03-17T23:43:01Z</published>
		<updated>2008-03-17T23:43:01Z</updated>
		<title>Flickr doing Video?</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/0ijh_Wwf02I/flickr-doing-video" />
		<id>tag:justinfrench.com,2008-03-17:083bed6ad50451eb341a307b6c00ee12/ea1cebf4015ce5e4cb97e3dade76b67d</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;Via &lt;a href="http://mashable.com/2008/03/16/flickr-video-april/"&gt;Mashable&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;According to a dig by Dan Farber of CNET on the matter, Yahoo, working on the heels of very eager anticipation, is planning to deliver “Flickr Video” sometime in April.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I find this really interesting.  Flickr has a massive, passionate, loyal community that have obviously embraced Flickr’s way of doing things.&lt;/p&gt;
	&lt;p&gt;Video feels like a natural progression for that community.  A large percentage of them probably dabble in video already, and they’re probably using another service to host and share that content.&lt;/p&gt;
	&lt;p&gt;Most cameras do video, so it makes perfect sense — if you’re going to experiment with moving pictures, you may as well share it with your existing Flickr network of friends and fans.&lt;/p&gt;
	&lt;p&gt;The other interesting point is that YouTube (owned by Google) is clearly has the upper hand with video.  Even searching for videos on Yahoo returns more YouTube results than Yahoo Video results (no scientific poll, of course), so Yahoo (owners of Flickr) may see some success leveraging Flickr’s community directly.&lt;/p&gt;
	&lt;p&gt;Above all else, I embrace the fact that Flickr had the discipline to go out there and solve one problem really well.  Along the way they amassed a large community, built a platform, learnt a lot and helped define the space they’re in.  They can take all this and apply it to video with ease.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/0ijh_Wwf02I" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/flickr-doing-video</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-02-08T02:23:06Z</published>
		<updated>2008-02-08T02:23:06Z</updated>
		<title>When you should keep your ideas to yourself</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/TDcFSAYVi4Y/when-you-should-keep-your-ideas-to-yourself" />
		<id>tag:justinfrench.com,2008-02-08:083bed6ad50451eb341a307b6c00ee12/7c77fa7a5f13088076caf03bcc84a1c9</id>
		<category term="Business" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://aphotoeditor.com/2008/02/06/how-to-manage-people/"&gt;Rob Haggart&lt;/a&gt; points to an interesting article over on Harvard Business titled &lt;a href="http://discussionleader.hbsp.com/goldsmith/2008/01/tips_for_managing_smart_people.html"&gt;When you should keep your ideas to yourself&lt;/a&gt;.  Take away quote for me is this:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;This could well be a case of trying to add “too much value,” and here’s the problem: the quality of the idea may go up 5% with my suggestions, but your commitment to its execution may go down 50%. It is no longer your idea; as your manager, I have now made it my idea.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Or, as Rob puts it:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Taking someone else’s idea and increasing the quality by 5% occurs at the price of a 50% decrease in their commitment to execution.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;It’s utterly obvious, and I think we already know this stuff deep down, but having it packaged up in a single sentence like that is always great useful.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/TDcFSAYVi4Y" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/when-you-should-keep-your-ideas-to-yourself</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-02-06T00:26:00Z</published>
		<updated>2008-02-08T01:53:11Z</updated>
		<title>Balanced Iteration Planning</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/cH9zSPpWx5A/balanced-iteration-planning" />
		<id>tag:justinfrench.com,2008-02-06:083bed6ad50451eb341a307b6c00ee12/26580fa507259fa2ba2609056fa973e5</id>
		<category term="RedBubble" />
		<category term="Agile" />
		<content type="html">
	&lt;p&gt;RedBubble does &lt;a href="http://en.wikipedia.org/wiki/Agile_software_development"&gt;agile development&lt;/a&gt; — it’s our own blend, but I guess it aligns best with the goals of &lt;a href="http://en.wikipedia.org/wiki/Scrum_(development"&gt;Scrum&lt;/a&gt;).&lt;/p&gt;
	&lt;p&gt;Both myself (something like a team leader) and &lt;a href="http://redbubble.com/people/peter"&gt;Pete&lt;/a&gt; (something like a product owner) both independently came up with an interesting proposal for creating a balanced iteration, so we’re going to give it a try.&lt;/p&gt;
	&lt;p&gt;Our backlog is overflowing with stories that we’re itching to build, and they each represent real value to the business.  We can’t do them all, it’s hard to stay focused, and it’s hard to say “no” to things we obviously need.&lt;/p&gt;
	&lt;p&gt;Typically the backlog consists of three types of stories:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;big things that will &lt;em&gt;win the war&lt;/em&gt; and align well with our long-term goals as a company&lt;/li&gt;
		&lt;li&gt;useful things that the community has been asking for (and which we agree they need)&lt;/li&gt;
		&lt;li&gt;shitty things that we aren’t excited about, but we have to do&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;In any given iteration (in our case, a week) we’re going to try to deliver a balance of the three.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;stay on track&lt;/li&gt;
		&lt;li&gt;show some love&lt;/li&gt;
		&lt;li&gt;do what we have to do&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; An iChat conversation with &lt;a href="http://www.thirdglance.com"&gt;James&lt;/a&gt; led us to the idea that it’s quite similar to a balanced diet — everyone knows what it is, and everyone knows why it’s a good idea, but occasionally (or frequently for some) the lure of tasty snacks and sugary treats pulls us away from things we know we’re supposed to be eating for our long-term health.&lt;/p&gt;
	&lt;p&gt;I’ll let you know how it goes in a few weeks.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/cH9zSPpWx5A" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/balanced-iteration-planning</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-02-05T04:02:00Z</published>
		<updated>2008-02-05T04:06:21Z</updated>
		<title>Floating legends in Firefox. Fail.</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/YsN-Gjpd8DE/floating-legends-in-firefox-fail" />
		<id>tag:justinfrench.com,2008-02-05:083bed6ad50451eb341a307b6c00ee12/af38b1732bd4a82a012027ed3c773cab</id>
		<category term="CSS" />
		<category term="Browsers" />
		<content type="html">
	&lt;p&gt;So I was trying to get a &lt;code&gt;legend&lt;/code&gt; inside a &lt;code&gt;fieldset&lt;/code&gt; to float left, so that I could float some radio inputs against it for a pretty standard horizontal form layout.&lt;/p&gt;
	&lt;p&gt;Works fine in Safari, won’t do it in Firefox.  Replacing the &lt;code&gt;legend&lt;/code&gt; with a &lt;code&gt;div&lt;/code&gt; or a &lt;code&gt;p&lt;/code&gt; or pretty much any block level element works, but I’m trying to be semantic if possible,&lt;/p&gt;
	&lt;p&gt;Finally, I search Bugzilla, and &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=269908"&gt;woop, there it is&lt;/a&gt;.  The built-in browser stylesheet uses &lt;code&gt;!important&lt;/code&gt; in two of it’s declarations:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
legend {
  padding-left: 2px;
  padding-right: 2px;
  border: none;
  position: static ! important;
  float: none ! important;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;code&gt;!important&lt;/code&gt; is the necessary evil of CSS, but I’m pretty sure it has no place in a base browser stylesheet (upon which all author and user stylesheets cascade).
	&lt;p&gt;So I started experimenting:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;nesting a &lt;code&gt;span&lt;/code&gt; inside the &lt;code&gt;legend&lt;/code&gt; and styling that didn’t work out&lt;/li&gt;
		&lt;li&gt;nesting a &lt;code&gt;div&lt;/code&gt; inside the &lt;code&gt;legend&lt;/code&gt; and styling that worked in Firefox, but broke Safari&lt;/li&gt;
		&lt;li&gt;wrapping the &lt;code&gt;legend&lt;/code&gt; in a &lt;code&gt;div&lt;/code&gt; with styling worked in Safari, but no love from Firefox&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;And then &lt;a href="http://redbubble.com/people/gbissett"&gt;Grant&lt;/a&gt; reminds me that you’re supposed to be able to override &lt;code&gt;!important&lt;/code&gt; styles with &lt;em&gt;new&lt;/em&gt; &lt;code&gt;!important&lt;/code&gt; styles if you match (or better) the specificity of the rule.  Tried that, still no love from Firefox.&lt;/p&gt;
	&lt;p&gt;So this is about the point where I assume there’s something special going on in Firefox, or something swept under the carpet, turn to the wider internet for help, and probably use something less semantic like a &lt;code&gt;h2&lt;/code&gt; or a &lt;code&gt;p&lt;/code&gt;.&lt;/p&gt;
	&lt;p&gt;Any ideas?&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/YsN-Gjpd8DE" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/floating-legends-in-firefox-fail</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-01-17T01:20:00Z</published>
		<updated>2008-01-17T05:09:24Z</updated>
		<title>The Leopard upgrade, and the stuff I still can't live without</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/6Hv1uQxxhrk/the-leopard-upgrade-and-the-stuff-i-still-cant-live-without" />
		<id>tag:justinfrench.com,2008-01-16:083bed6ad50451eb341a307b6c00ee12/c2c49ac50275ea1eda324ea0e526b1fc</id>
		<category term="Apple" />
		<category term="OS X" />
		<content type="html">
	&lt;p&gt;I finally dusted off that Leopard disc on my desk and installed it yesterday.  Rather than an upgrade, I choose to clone Tiger onto an external drive with SuperDuper!, then installed Leopard on a clean hard drive.&lt;/p&gt;
	&lt;p&gt;Much like renting (where you’re forced to contemplate the value of everything you own every year or two as you move around), I really love the opportunity to start fresh with a new OS, ensuring that (at least for a while) everything you install is something you really &lt;em&gt;need&lt;/em&gt;.&lt;/p&gt;
	&lt;p&gt;The results are pretty interesting after 24 hours.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;my Applications folder is just 499mb, down from 2.3GB (!) with at least 20 fewer apps installed&lt;/li&gt;
		&lt;li&gt;my Library is less than half it’s original 3GB of bloat&lt;/li&gt;
		&lt;li&gt;the system Library is nearly 5GB, but it’s dropped down from 14&lt;/li&gt;
		&lt;li&gt;in total, I’ve got an &lt;em&gt;extra&lt;/em&gt; 50GB of disk space I didn’t have yesterday&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;What survived?  With some obvious exceptions, it’s mostly stuff from indie developers:&lt;/p&gt;
	&lt;p&gt;Installed within 5 minutes:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://www.blacktree.com/"&gt;Quicksilver&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.mani.de/en/software/macosx/littlesecrets/index.html"&gt;Little Secrets&lt;/a&gt; (it holds all my usernames, passwords and miscellaneous details for pretty much everything in my life)&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Installed within an hour:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://culturedcode.com/things/"&gt;Things&lt;/a&gt; (it now rules my life)&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://appzapper.com/"&gt;AppZapper&lt;/a&gt; (it was handy for tracking down files on my Tiger install that my favorite apps depended on, like preference files and bundles)&lt;/li&gt;
		&lt;li&gt;iLife 08&lt;/li&gt;
		&lt;li&gt;iWork 08&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Installed within 24 hours:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://www.theonline.org/cocoamysql/"&gt;CocoaMySQL-SBG&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.linotype.com/fontexplorerX"&gt;Linotype FontExplorer X&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.newsgator.com/Individuals/NetNewsWire/Default.aspx"&gt;NetNewsWire&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;Adobe CS3&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Predicted installs in the next week:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href="http://www.omnigroup.com/applications/omnigraffle/"&gt;OmniGraffle&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://simonhaertel.de/"&gt;Quinn&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.parallels.com/"&gt;Parallels&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.shirt-pocket.com/SuperDuper/"&gt;SuperDuper!&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.flip4mac.com/"&gt;Flip4Mac&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Some other things I had to do really quick:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;I don’t even &lt;em&gt;use&lt;/em&gt; the scroll arrows much, but I still had to move them to the top and bottom (rather than both at the bottom) because even after all this time, they still distract me&lt;/li&gt;
		&lt;li&gt;Allan’s &lt;a href="http://blog.macromates.com/2006/word-movement-in-terminal/"&gt;tips for getting option-left and option-right to act like the rest of OS X when using Terminal&lt;/a&gt; (skipping back and forward one word) is pretty much all need to do to feel at home in Terminal&lt;/li&gt;
	&lt;/ul&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/6Hv1uQxxhrk" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/the-leopard-upgrade-and-the-stuff-i-still-cant-live-without</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-01-16T23:50:00Z</published>
		<updated>2008-02-26T02:33:10Z</updated>
		<title>Design Police</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/k6mxS5PZpj0/design-police" />
		<id>tag:justinfrench.com,2008-01-16:083bed6ad50451eb341a307b6c00ee12/89b750eabbc4319f90950022def4e34d</id>
		<category term="Fun" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://www.design-police.org/"&gt;&lt;img src="/images/7t.png" title="" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;(Via co-worker &lt;a href="http://www.redbubble.com/people/cannboys"&gt;Ben&lt;/a&gt;)&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/k6mxS5PZpj0" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/design-police</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-01-15T00:28:00Z</published>
		<updated>2008-01-17T03:11:20Z</updated>
		<title>8 hour school day?</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/rXzjvLiaO_4/8-hour-school-day" />
		<id>tag:justinfrench.com,2008-01-15:083bed6ad50451eb341a307b6c00ee12/fd943253a787ac5de603065ff6484e09</id>
		
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://daringfireball.net/linked/2008/january#mon-14-early_bird"&gt;Gruber on an NY Times article about education&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;But she also argues that the school day should be expanded from 6.5 to 8 hours, quoting some jackass who says “Trying to cram everything our 21st-century students need into a 19th-century six-and-a-half-hour day just isn’t working.” The last thing kids need is to be cooped up in school for more hours each day.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;I have no kids, so I’m probably utterly under-qualified to talk about this stuff, but I was a kid once.  I’d actually be in favor of an 8-hour school day if it meant abolishing homework and/or letting kids explore the aspects of their learning that interest them the most.&lt;/p&gt;
	&lt;p&gt;As a bonus, parents wouldn’t have to spend a fortune on child care for those extra hours they were at work, and time spent at home could actually revolve around the home and family, rather than an extension of school.&lt;/p&gt;
	&lt;p&gt;No idea what it’s like elsewhere, but in Australia, kids (especially in high school) are absolutely hammered with an incredible amount of work to be completed outside of school hours.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/rXzjvLiaO_4" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/8-hour-school-day</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2008-01-08T22:02:00Z</published>
		<updated>2008-01-17T03:11:23Z</updated>
		<title>I can't believe it took me this long to commit to Rails</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/qN6Ccx6OW34/i-cant-believe-it-took-me-this-long-to-commit-to-rails" />
		<id>tag:justinfrench.com,2008-01-08:083bed6ad50451eb341a307b6c00ee12/0b245efd02897828bf9198351df6dd0a</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;... and it’s only a pissy &lt;a href="http://dev.rubyonrails.org/changeset/8597"&gt;documentation patch&lt;/a&gt;.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/qN6Ccx6OW34" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/i-cant-believe-it-took-me-this-long-to-commit-to-rails</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-12-20T11:11:48Z</published>
		<updated>2007-12-20T11:11:48Z</updated>
		<title>Design, a Beautiful Web Development Bookmarklet</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Nj03_Es7NiQ/design-a-beautiful-web-development-bookmarklet" />
		<id>tag:justinfrench.com,2007-12-20:083bed6ad50451eb341a307b6c00ee12/1032a239a1beec98c1b93dec174041a0</id>
		<category term="CSS" />
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://www.sprymedia.co.uk/article/Design"&gt;This is seriously great&lt;/a&gt;... in-browser rulers, cross hairs, measuring things and &lt;strong&gt;grids&lt;/strong&gt;.  Oh yeah.  For the record, I also love &lt;a href="http://westciv.com/mri/"&gt;MRI&lt;/a&gt; and &lt;a href="http://westciv.com/xray/"&gt;XRAY&lt;/a&gt; by John Allsop/Westciv.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Nj03_Es7NiQ" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/design-a-beautiful-web-development-bookmarklet</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-12-16T11:55:56Z</published>
		<updated>2007-12-16T11:55:56Z</updated>
		<title>Optionally Nested Controllers</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/piyL_grnxqs/optionally-nested-controllers" />
		<id>tag:justinfrench.com,2007-12-16:083bed6ad50451eb341a307b6c00ee12/8688f6b56ba548bf7fe4811617cb3fdf</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;I’ve seen this asked a few times in #rubyonrails and #roro IRC channels, so rather than knock up a code example every time, maybe I can just point people here.&lt;/p&gt;
	&lt;h3&gt;The Problem&lt;/h3&gt;
	&lt;p&gt;Some people like nested resource URLs like &lt;code&gt;/people/21/images/45&lt;/code&gt;, instead of flat URLs like &lt;code&gt;/images/45&lt;/code&gt;, and some people like to have both accessible as options.  Rails’ Routing can do this easy.  Some people consider these two different resources, so they’ll have an &lt;code&gt;ImagesController&lt;/code&gt; and a &lt;code&gt;PeopleImagesController&lt;/code&gt;.  Others think that’s horribly repetitive for what they’re doing with their code, so they want it all to go through one &lt;code&gt;ImagesController&lt;/code&gt; with an optional parent object or scoping.&lt;/p&gt;
	&lt;p&gt;This is for those people, scratching their heads, wondering how that’s done cleanly.&lt;/p&gt;
	&lt;h3&gt;A Solution (though most certainly not the only solution)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;
 class ImagesController &amp;lt; ApplicationController
   def index
     @images = parent.find(:all)
   end
   def show
     @image = parent.find(params[:id])
   end
   def new
     @image = parent.new
   end
   # ...
   protected
   def parent
     params[:person_id] ? 
       Person.find(params[:person_id]).images :
       Image
   end
 end
&lt;/code&gt;&lt;/pre&gt;
	&lt;h3&gt;But what does it do?&lt;/h3&gt;
	&lt;p&gt;Given the URL /people/24/images/..., &lt;code&gt;params[:person_id] will be set.  If it's found @parent&lt;/code&gt; returns an images collection scoped to that person upon which we can perform our &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;new&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt; (etc) methods on.  If it’s not present, we just do them directly on the &lt;code&gt;Image&lt;/code&gt; class.&lt;/p&gt;
	&lt;p&gt;It’s scoped to the person if there is one in the URL, and isn’t if there isn’t.&lt;/p&gt;
	&lt;p&gt;There are many ways to tackle this kind of problem, and plugins like &lt;a href="http://mr.hamptoncatlin.com/"&gt;make_resourceful&lt;/a&gt; do similar things and are a great kick in the right direction.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/piyL_grnxqs" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/optionally-nested-controllers</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-12-16T11:29:50Z</published>
		<updated>2007-12-16T11:29:50Z</updated>
		<title>Comments are off for a bit</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/KkyEWXdHUms/comments-are-off-for-a-bit" />
		<id>tag:justinfrench.com,2007-12-16:083bed6ad50451eb341a307b6c00ee12/39e243c3e3b3851a2be6a7aea4873704</id>
		<category term="This Site" />
		
		<content type="html">
	&lt;p&gt;Hooray for spammers.  I’ve never been a big fan of comments anyway, so maybe I’ll accidentally leave them off for good.  Who knows.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/KkyEWXdHUms" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/comments-are-off-for-a-bit</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-12-04T05:42:26Z</published>
		<updated>2007-12-04T05:42:26Z</updated>
		<title>Fixtures in Rails 2.0</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Upe7J9dqtwg/fixtures-in-rails-20" />
		<id>tag:justinfrench.com,2007-12-04:083bed6ad50451eb341a307b6c00ee12/7be9c9c9730c5561fb04b1a4a7406bb1</id>
		
		
		<content type="html">
	&lt;p&gt;Don’t know how I missed this earlier, but fixtures have had some love in Rails 2.0 — &lt;a href="http://media.railscasts.com/videos/081_fixtures_in_rails_2.mov"&gt;this&lt;/a&gt; just feels so much nicer!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Upe7J9dqtwg" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/fixtures-in-rails-20</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-12-02T11:04:00Z</published>
		<updated>2007-12-02T11:04:00Z</updated>
		<title>A small, small announcement</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/H0Xt2awXxKY/a-small-small-announcement" />
		<id>tag:justinfrench.com,2007-12-02:083bed6ad50451eb341a307b6c00ee12/badea82fbda2ca2f4f36de9fccda0a1a</id>
		
		
		<content type="html">
	&lt;p&gt;I’m certain hardly any one cares, but I’ve made a decision.  If you want me to buy things from your online store, I should be able to do it without signing up for an account, agreeing to a 3000-word legal document or fighting to ensure you don’t add me to your email lists.&lt;/p&gt;
	&lt;p&gt;What is this, the ‘90s?&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/H0Xt2awXxKY" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/a-small-small-announcement</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-11-15T00:41:47Z</published>
		<updated>2007-11-15T00:41:47Z</updated>
		<title>Rituals</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/RGE7Z82zSw0/rituals" />
		<id>tag:justinfrench.com,2007-11-15:083bed6ad50451eb341a307b6c00ee12/f3f433e206535dd293bfd9bb06e7b415</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;Rituals have become a massive part of RedBubble culture over the last few months.  Our build cycles are based loosely around one month chunks of work, with weekly iterations inside them, with daily bursts of work inside each of those.&lt;/p&gt;
	&lt;p&gt;Each of them is punctuated by some form of gathering – a 5 minute daily standup, an hour-long weekly demo/review of the work we’ve done, and a longer monthly get together to talk about where we’ve been, and where we’re headed.&lt;/p&gt;
	&lt;p&gt;That probably sounds like a whole lot of meetings, but they’re typically not the toxic kind of meeting that everyone hates.  Especially the daily stand-up.&lt;/p&gt;
	&lt;p&gt;The beauty of all these rituals is that they add some form of structure to the whirlwind of chaos we’re working in.  You vent, complain, boast, clear your mind, reset your focus and get back to it.&lt;/p&gt;
	&lt;p&gt;And the RedBubble community is picking up on these rituals and embracing them wholeheartedly.  We release whatever we’ve done almost every week, so Thursday has become &lt;a href="http://www.redbubble.com/people/redbubble/journal/362496-redbubble-thursday"&gt;RedBubble Thursday&lt;/a&gt; — a celebration of what we’ve delivered, and what we’re doing next.&lt;/p&gt;
	&lt;p&gt;The “wow”, “yay” and “thank you” comments flood in just seconds after we announce the changes, and it seems to inject a massive dose of energy into the community.  They see this thing changing and evolving in front of them, they see us responding to their needs and they see us pull out a few tricks and surprises they never expected.&lt;/p&gt;
	&lt;p&gt;Most agile development books go into these rituals in much more detail, and I’m almost certain most books about “communities on the web” would have plenty to say about it too.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/RGE7Z82zSw0" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/rituals</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-11-13T23:21:00Z</published>
		<updated>2007-11-13T23:26:57Z</updated>
		<title>Introducing Meta Serif</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Y4BvnB00RGg/introducing-meta-serif" />
		<id>tag:justinfrench.com,2007-11-13:083bed6ad50451eb341a307b6c00ee12/3208c6b1ddcf962785b0cedb4dc2b7a5</id>
		
		
		<content type="html">
	&lt;blockquote&gt;
		&lt;p&gt;The most influential sans serif of the digital revolution now has a serif companion.&lt;br /&gt;
— &lt;a href="http://www.fontshop.com/features/newsletters/nov2007_a/"&gt;November Font Shop newsletter&lt;/a&gt;&lt;/p&gt;
	&lt;/blockquote&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Y4BvnB00RGg" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/introducing-meta-serif</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-11-13T11:31:56Z</published>
		<updated>2007-11-13T11:31:56Z</updated>
		<title>You Don't Need a Development Manager</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/3ADyX8qhfRg/you-dont-need-a-development-manager" />
		<id>tag:justinfrench.com,2007-11-13:083bed6ad50451eb341a307b6c00ee12/77ada2ecf6b1f57f33c1d9477a101b8d</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;Some interesting things have happened at &lt;a href="http://www.redbubble.com/"&gt;RedBubble&lt;/a&gt; over the last year (already?).  One that’s been at the forefront of my thinking over the last few weeks is how we don’t seem to need a Development Manager at all.&lt;/p&gt;
	&lt;p&gt;We had one.  It wasn’t me, but I’ve been there before.  It was the typical role, with the usual stuff:&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;know the system, be sure it works&lt;/li&gt;
		&lt;li&gt;lead the team &amp; make sure things get done&lt;/li&gt;
		&lt;li&gt;make sure “the business” doesn’t hassle “the developers” with crazy ideas and scope creep&lt;/li&gt;
		&lt;li&gt;make sure the dev team is happy and productive&lt;/li&gt;
		&lt;li&gt;manage the project timeline and backlog&lt;/li&gt;
		&lt;li&gt;estimate and plan out the dev team’s time&lt;/li&gt;
		&lt;li&gt;argue over deadlines&lt;/li&gt;
		&lt;li&gt;translate requirements into tasks and stories that can be implemented&lt;/li&gt;
		&lt;li&gt;manage expectations&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Adopting a more agile development process (&lt;a href="http://en.wikipedia.org/wiki/Scrum_(development)"&gt;Scrum&lt;/a&gt;, or something like it, if you’re interested) certainly removed a lot of the crap from this role and pushed things in the right direction, but it still didn’t work out.&lt;/p&gt;
	&lt;p&gt;Really, this is far too much work for one person to do well, so what’s the point?  The role stinks of big business, it gets in the way of actually doing stuff, it frustrates the shit out of everyone and it’s absolutely destined to fail in a start-up environment.&lt;/p&gt;
	&lt;p&gt;None of this is the manager’s fault, by the way.&lt;/p&gt;
	&lt;p&gt;What do we do instead?  As a team, we manage the team. We have smart people with a complimentary and multidisciplinary skill set, so we farm out different parts of the role amongst ourselves.&lt;/p&gt;
	&lt;p&gt;Pete (the boss) took on all the human resources stuff and assumed.  I took on a lot of the iteration planning &amp; day-to-day leadership.  John and Dave took on the systems architecture.  Grant , Kath and Xavier all pushed in new directions to pick up the slack. The entire team helps with bugs, planning and estimation.  We basically self-organise and keep each other in line.&lt;/p&gt;
	&lt;p&gt;No-one stands between the person who needs stuff done and the person who can do it, no one holds everything in their head, no one plays the role of the gatekeeper and no one has the impressive title on their business card.&lt;/p&gt;
	&lt;p&gt;We’re getting things done faster this way, no doubt, and that’s incredibly important for a start-up.&lt;/p&gt;
	&lt;p&gt;However, this huge pay-off would not be possible without some boundaries and an open, honest dialogue — we know how much work we can do in an average week, so we’re not asked to commit to anything unrealistic, and we’re quite comfortable telling Pete that he’s asking us to build something far too vague, or that his cheeky 1 hour “simple text changes” card was incredibly optimistic.&lt;/p&gt;
	&lt;p&gt;There’s an overhead to this of course.  The time we spend managing ourselves is time we don’t spend writing code or pushing pixels around, but I’m convinced we’re still &lt;em&gt;way&lt;/em&gt; in front.&lt;/p&gt;
	&lt;p&gt;If you’re looking to hire a manager, I can highly recommend sniffing around inside your own team first.  Or if your manager is overloaded (they all are, right?) don’t tell them to suck it up — ask them what they can offload to others in the team to free up some time.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/3ADyX8qhfRg" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;One that’s been at the forefront of my thinking over the last few weeks is how we don’t seem to need a Development Manager at all.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/you-dont-need-a-development-manager</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-11-06T10:35:57Z</published>
		<updated>2007-11-06T10:35:57Z</updated>
		<title>DataMapper</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/bZo1jCvIw4o/datamapper" />
		<id>tag:justinfrench.com,2007-11-06:083bed6ad50451eb341a307b6c00ee12/e172c219dad83e2bd88f6b2f756761d1</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;blockquote&gt;
		&lt;p&gt;&lt;a href="http://datamapper.rubyforge.org/"&gt;DataMapper&lt;/a&gt; is an Object Relational Mapper written in Ruby. The goal is to create an ORM which is fast, thread-safe and feature rich.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Looks like something interesting to try out alongside &lt;a href="http://sinatra.rubyforge.org/"&gt;Sinatra&lt;/a&gt; next time I need to hack together a quick database-backed website and would rather not eat up 60+meg of RAM for each Mongrel.&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Found a bug or want a feature? Tired of dealing with the bureaucracy that other ORM maintainers force upon you?&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Gee, I wonder which ORM they’re talking about?&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/bZo1jCvIw4o" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/datamapper</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-10-19T01:03:00Z</published>
		<updated>2007-10-19T01:05:31Z</updated>
		<title>It Only Takes a Minute</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/GkD7OJoAA30/it-only-takes-a-minute" />
		<id>tag:justinfrench.com,2007-10-19:083bed6ad50451eb341a307b6c00ee12/fc89776d98f49a268f8e75d232d2b61c</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;Next week, amongst many other far more interesting things, &lt;a href="http://www.redbubble.com/"&gt;RedBubble&lt;/a&gt; will be rolling out a small change asking our artists to specify the currency in which they wish to be paid.&lt;/p&gt;
	&lt;p&gt;We started out just using their browsing preference (“show me prices in USD”), but it turns out that if they change this along the way, it creates major accounting headaches which we’d rather not write software to dance around right now (bigger fish, etc).&lt;/p&gt;
	&lt;p&gt;So, the solution is a browsing preference (change it as often as you like) and a payment preference (can’t be easily changed).&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/xshay"&gt;Xavier&lt;/a&gt; could have easily pushed it out the door with some dry “cannot be changed” text, but it only took him a few seconds longer to go the extra mile and make that text a little warmer, informative and personal:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;“Which currency would you like to be paid in? For reasons only our accountant understands, this cannot be changed after you have set it.”&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;&lt;a href="http://gettingreal.37signals.com/ch09_Copywriting_is_Interface_Design.php"&gt;Copywriting is Interface Design&lt;/a&gt;, and I think it’s really important that teams are encouraged to inject a little bit of their own personality and natural language into their work wherever possible.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/GkD7OJoAA30" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/xshay"&gt;Xavier&lt;/a&gt; could have easily pushed it out the door with some dry “cannot be changed” text, but it only took him a few seconds longer to go the extra mile and make that text a little warmer, informative and personal:&lt;/p&gt;


 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/it-only-takes-a-minute</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-10-04T00:55:00Z</published>
		<updated>2008-05-01T03:39:15Z</updated>
		<title>Any?</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/a_bWks_VR5E/any" />
		<id>tag:justinfrench.com,2007-10-04:083bed6ad50451eb341a307b6c00ee12/a9ea6a0c1f1a35669787ae4f39730cc1</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;Behold! Ruby weirdness.  So I was hanging out in our utterly messy views, and thought to myself “what I want is the &lt;em&gt;opposite&lt;/em&gt; of &lt;code&gt;Array#empty?&lt;/code&gt;, and I’d call it Array#any?”.&lt;/p&gt;
	&lt;p&gt;So I fire up the console and have a play.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt;&amp;gt; [].any?
=&amp;gt; false
&amp;gt;&amp;gt; [1,2].any?
=&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Fantastic!  But wait, &lt;a href="http://rhnh.net"&gt;Xavier&lt;/a&gt; shows me the dark side of &lt;code&gt;any?&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt;&amp;gt; [false].any?
=&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Gah, so &lt;code&gt;any?&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt; if any of the values in the Array are &lt;code&gt;true&lt;/code&gt;, &lt;em&gt;not&lt;/em&gt; if there’s something (anything) in the Array, as I’d hoped.  I guess someone, at some point, had a reason for that.&lt;/p&gt;
	&lt;p&gt;Of course &lt;code&gt;!my_array.empty?&lt;/code&gt; is the answer, but I like even better answers.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/a_bWks_VR5E" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/any</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-10-01T00:18:03Z</published>
		<updated>2007-10-01T00:18:03Z</updated>
		<title>Web Directions 07: The Myths of Innovation</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/bC1-fpQ_iNg/web-directions-07-the-myths-of-innovation" />
		<id>tag:justinfrench.com,2007-10-01:083bed6ad50451eb341a307b6c00ee12/9482cdf194c1ebf97c9112e77b1b9cb5</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;Ah screw it — it’s much easier to just write about all these &lt;a href="http://www.webdirections.org"&gt;Web Directions&lt;/a&gt; things individually, rather than some mythical mega-post.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.scottberkun.com/"&gt;Scott Berkun&lt;/a&gt; gave another great presentation on &lt;em&gt;The Myths of Innovation&lt;/em&gt;. I’ve placed an order for &lt;a href="http://www.amazon.com/Myths-Innovation-Scott-Berkun/dp/0596527055"&gt;his book&lt;/a&gt; and subscribed to his feed.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/bC1-fpQ_iNg" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Scott Berkun gave another great presentation on &lt;em&gt;The Myths of Innovation&lt;/em&gt;.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/web-directions-07-the-myths-of-innovation</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-09-30T23:37:00Z</published>
		<updated>2007-10-01T00:29:46Z</updated>
		<title>Web Directions 07: The Mob Rules</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/7Ubl3brkguM/the-mob-rules" />
		<id>tag:justinfrench.com,2007-09-30:083bed6ad50451eb341a307b6c00ee12/425fc55cbd732bfc2c6b642e7abd23fb</id>
		<category term="Web Industry" />
		
		<content type="html">
	&lt;p&gt;The one presentation from &lt;a href="http://webdirections.org/"&gt;Web Directions&lt;/a&gt; that remains at the very front of my mind is &lt;a href="http://markpesce.com/"&gt;Mark Pesce&lt;/a&gt;’s closing keynote, &lt;a href="http://blog.futurestreetconsulting.com/?p=39"&gt;The Mob Rules&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;I could pull a million quotes from it, or even quote the whole thing, but here’s two:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Google resisted the mashup.  Claimed mashups violated their terms of use.  Mashups come from the mob, the street finding its own use for things.    The mob pushed on through; Google bowed down and obeyed.  The most powerful institution of the Internet era, pushed around like a child’s toy.  Ponder that.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;blockquote&gt;
		&lt;p&gt;Even worse, for those who are raising a hew and cry about the “theft” of their precious content, the more they scream, the more they thrash about, the stronger the mob becomes.  Consider: filesharing has only grown more pervasive despite every attempt of every copyright holder to bring it to heel.  Each move has been met with a counter-move.  There is no safety in copyright, nor any arguing with the mob.  Music and movies are freely and broadly available, and will remain so into the indefinite future.  Sadly, we’re now seeing that same, sorry battle repeated in double-time as advertisers – and those dependent upon them – assert an authority they no longer possess.&lt;/p&gt;
	&lt;/blockquote&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/7Ubl3brkguM" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;I still want to find time for a much more in depth review of Web Directions (short answer, it was fantastic, despite my own woeful contribution!), but the one presentation that remains at the very front of my mind is Mark Pesce’s closing keynote, The Mob Rules.&lt;/p&gt;


 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/the-mob-rules</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-09-30T23:01:55Z</published>
		<updated>2007-09-30T23:01:55Z</updated>
		<title>HTTP Errors</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/S9YWlL3Dneo/http-errors" />
		<id>tag:justinfrench.com,2007-09-30:083bed6ad50451eb341a307b6c00ee12/ae82452bb668e783f5a592df5409699b</id>
		
		
		<content type="html">
	&lt;p&gt;&lt;a href="http://www.flickr.com/photos/jessefriedman/1435220149/"&gt;HTTP Errors&lt;/a&gt; via &lt;a href="http://www.redbubble.com/people/dave"&gt;Dave Cheney&lt;/a&gt;, our fearless sysadmin.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/S9YWlL3Dneo" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/http-errors</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-09-27T03:51:57Z</published>
		<updated>2007-09-27T03:51:57Z</updated>
		<title>Well, that sucked</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/tq5Nrj0D-Ko/well-that-sucked" />
		<id>tag:justinfrench.com,2007-09-27:083bed6ad50451eb341a307b6c00ee12/0d923768e47f223dc84097034599b7ff</id>
		<category term="Me" />
		
		<content type="html">
	&lt;p&gt;Man, being entertaining and interesting &lt;a href="http://www.webdirections.org"&gt;on stage&lt;/a&gt; for an hour is hard hard work.  I think I’ll just leave it at that!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/tq5Nrj0D-Ko" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/well-that-sucked</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-09-22T23:36:00Z</published>
		<updated>2007-09-22T23:39:59Z</updated>
		<title>Write a Blogging Engine</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/5BbxCVmK3j4/write-a-blogging-engine" />
		<id>tag:justinfrench.com,2007-09-22:083bed6ad50451eb341a307b6c00ee12/ed4643d2401d8ebadc738d2a372e785c</id>
		<category term="Rails" />
		<category term="Web Industry" />
		<content type="html">
	&lt;p&gt;From &lt;a href="http://ifacethoughts.net/2007/09/19/want-to-learn-web-programming-write-a-blog-engine/"&gt;Want To Learn Web Programming? Write A Blog Engine&lt;/a&gt; by &lt;a href="http://ifacethoughts.net/"&gt;Abhijit Nadgouda&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;What is the best way learning any kind of programming? Write programs! I sincerely believe that a blog engine is one of the rare pieces which employs all the basics of Web programming but can be simple enough to understand.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Couldn’t agree more.  This is my favorite conversation point for interviewing web app developers.&lt;/p&gt;
	&lt;ul&gt;
		&lt;li&gt;if you have no idea what the problem domain is (if you don’t know enough about blogging), we can cut the interview short, because it’s clear you don’t “get” the internet at the level I was hoping for&lt;/li&gt;
		&lt;li&gt;the problem domain is also small enough that you can hold all the pieces in your head&lt;/li&gt;
		&lt;li&gt;you can sketch the model on the back of a napkin in a Fitzroy café&lt;/li&gt;
	&lt;/ul&gt;
	&lt;p&gt;Even better, we tend to interview quite a lot of PHP/Java/Python developers who &lt;em&gt;want&lt;/em&gt; to work with the Rails framework, but if they can’t talk about the model or implementation, it’s pretty clear to me that they haven’t spent much time looking into it at all.  From DHH’s 20-minute-video, through to Mephisto, Simplelog and even Radiant, there’s plenty of resources out there.&lt;/p&gt;
	&lt;p&gt;“What models would we need for a simple blog?” is almost a freebie, but many stumble.&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/5BbxCVmK3j4" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/write-a-blogging-engine</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-09-07T21:40:24Z</published>
		<updated>2007-09-07T21:40:24Z</updated>
		<title>"Mind the Gap Please"</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/8Yfep7kl_ts/mind-the-gap-please" />
		<id>tag:justinfrench.com,2007-09-07:083bed6ad50451eb341a307b6c00ee12/28590f7aed6121b327684983def4d7c6</id>
		<category term="Me" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;So here we are in London.  We had a one night stopover in Singapore which was great (call me crazy, but it felt just like Melbourne, only bigger), then a 13 hour flight to Heathrow.&lt;/p&gt;
	&lt;p&gt;We spent a few days hanging out with Nat (the wonderful Aussie ex-pat who set Kate and me up about 4 years back), looked at lots of old buildings Cantebury and Rochester, and now we’re here in the middle of an absolutely &lt;em&gt;amazing&lt;/em&gt; city with so much history.&lt;/p&gt;
	&lt;p&gt;We’re here for a few more days (Portabello Market tomorrow, and a bus tour out to Stone Henge on Monday), then we get the Eurostar across to Paris for a few days of awkwardness (neither of us can speak a word of French, which is probably even more confusing given my surname), shortly followed by a flight to Berlin for a few days of sightseeing and RailsConf Europe.&lt;/p&gt;
	&lt;p&gt;Yes, the credit card is going to get a work-out.&lt;/p&gt;
	&lt;p&gt;See (some of) you in Berlin for beers and geek stuff.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/8Yfep7kl_ts" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;So here we are in London.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/mind-the-gap-please</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-08-29T12:12:05Z</published>
		<updated>2007-08-29T12:12:05Z</updated>
		<title>Hello, Install This Plugin Now</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/FFZ-vvJhUEM/hello-install-this-plugin-now" />
		<id>tag:justinfrench.com,2007-08-29:083bed6ad50451eb341a307b6c00ee12/520e555d9ffbad33caf49a5aa61245d4</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;Courtesy of &lt;a href="http://www.robbyonrails.com/articles/2007/08/28/rails-development-performance-tip-dev_mode_performance_fixes"&gt;Robby Russell&lt;/a&gt;, I just stumbled upon Josh Goebel’s &lt;a href="http://svn.techno-weenie.net/projects/plugins/dev_mode_performance_fixes/"&gt;dev_mode_performance_fixes&lt;/a&gt; plugin, which really does seem to work as advertised.&lt;/p&gt;
	&lt;p&gt;Clicking around the RedBubble application in development mode feels &lt;em&gt;way&lt;/em&gt; faster — 6x faster at least, mainly because we have stacks of image-heavy pages, with each image passed through the Rails stack on every request (yeah, they’re cached in production, but development mode is just painfully slow out-of-the-box).&lt;/p&gt;
	&lt;p&gt;So far, so good.  Most changes seem to be picked up without restarting Mongrel (although a few random changes to inherited controllers needed a restart).&lt;/p&gt;
	&lt;p&gt;Three cheers!&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/FFZ-vvJhUEM" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/hello-install-this-plugin-now</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-08-23T02:30:00Z</published>
		<updated>2007-08-23T02:35:17Z</updated>
		<title>Black Tees are Here</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/ffONSNaJo7Y/black-tees-are-here" />
		<id>tag:justinfrench.com,2007-08-23:083bed6ad50451eb341a307b6c00ee12/bdd645a77637c58b6d039a68a8c32336</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;I’m really excited that we’ve &lt;em&gt;finally&lt;/em&gt; launched black tees on RedBubble.  We launched just two hours ago and the community has already started pumping out some amazing stuff.&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/resisto/clothing/134851-wound-up-black-t-only"&gt;&lt;img src="http://images-0.redbubble.com/rbimages/works_tshirt_main_view/wound-up_blackcolour_2.png.jpg?color=black&amp;style=Mens" style="width:75%;"&gt;&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/thickblackoutline/clothing/135002-sushi-traffic-light-night-driving"&gt;&lt;img src="http://images-2.redbubble.com/rbimages/works_tshirt_main_view/sushitrafficnight.png.jpg?color=black&amp;style=Mens" style="width:75%;"&gt;&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/thickblackoutline/clothing/134922-little-maiko"&gt;&lt;img src="http://images-2.redbubble.com/rbimages/works_tshirt_main_view/littlemaiko.png.jpg?color=black&amp;style=Womens" style="width:75%;"&gt;&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;And since I’m a shameless entrepreneur and want a new car, everyone should buy some of my stuff:&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/justin/clothing/135033-hello-flossy"&gt;&lt;img src="http://images-1.redbubble.com/rbimages/works_tshirt_main_view/flossy_2.png.jpg?color=black&amp;style=Womens" style="width:75%;"&gt;&lt;/a&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/people/justin/clothing/10162-loud"&gt;&lt;img src="http://images-2.redbubble.com/rbimages/works_tshirt_main_view/leds2.png.jpg?color=black&amp;style=Mens" style="width:75%;"&gt;&lt;/a&gt;&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/ffONSNaJo7Y" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/black-tees-are-here</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-08-21T04:53:00Z</published>
		<updated>2007-08-21T04:54:34Z</updated>
		<title>Overheard</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/mQsRGpuEh-Y/overheard" />
		<id>tag:justinfrench.com,2007-08-21:083bed6ad50451eb341a307b6c00ee12/6ef1f4d0cb2df0edbe3f5caccef2fd15</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;blockquote&gt;
		&lt;p&gt;“I reckon we apply the 80/20 rule to this IE bug on writing – it’s 80% working, and we’ll fix it in about 20 iterations”&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;— &lt;a href="http://www.redbubble.com/people/gbissett"&gt;Grant Bissett&lt;/a&gt;, RedBubble&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/mQsRGpuEh-Y" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/overheard</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-08-07T08:13:00Z</published>
		<updated>2007-08-07T08:16:17Z</updated>
		<title>Warm and Fuzzy</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/Fr0M_RUXtmU/warm-and-fuzzy" />
		<id>tag:justinfrench.com,2007-08-07:083bed6ad50451eb341a307b6c00ee12/5021cf97c4cda510cc84a7056f8e5b8f</id>
		<category term="RedBubble" />
		
		<content type="html">
	&lt;p&gt;Seeing overwhelmingly positive, glowing reviews &lt;a href="http://www.marialanger.com/2007/08/05/redbubble-cards/"&gt;like this one&lt;/a&gt; of our products makes all the hard work really seem worthwhile.&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;These are, by far, the best quality photo greeting cards I have every seen. I am pleased beyond measure. I am, in fact, tickled pink.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Lessons learned?  We pushed really hard to get those cards right.  They consumed a &lt;em&gt;lot&lt;/em&gt; of our resources in both tech, R&amp;D and fulfillment — and it paid off.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/Fr0M_RUXtmU" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Seeing overwhelmingly positive, glowing reviews &lt;a href="http://www.marialanger.com/2007/08/05/redbubble-cards/"&gt;like this one&lt;/a&gt; of &lt;a href="http://www.redbubble.com/'s"&gt;RedBubble&lt;/a&gt; products makes all the hard work really seem worthwhile.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/warm-and-fuzzy</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-08-02T07:46:00Z</published>
		<updated>2007-08-02T07:47:52Z</updated>
		<title>RedBubble is Hiring a Web Designer</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/ZWTuAzUNpz4/redbubble-is-hiring-a-web-designer" />
		<id>tag:justinfrench.com,2007-08-02:083bed6ad50451eb341a307b6c00ee12/1a2d7b2cc2091a35819544965081a614</id>
		<category term="RedBubble" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;Copied straight from &lt;a href="http://jobs.37signals.com/jobs/1940"&gt;our ad&lt;/a&gt; on 37signals’ Job Board:&lt;/p&gt;
	&lt;p&gt;&lt;blockquote&gt;&lt;/p&gt;
	&lt;p&gt;&lt;a href="http://www.redbubble.com/"&gt;RedBubble&lt;/a&gt; is looking for a standards-based web designer to help create polished user interfaces. We’d really like to meet someone with strong front-end development skills (you’ll know what that entails), as well as the visual design nous required to create usable and elegant screens.&lt;/p&gt;
	&lt;p&gt;Standards-based CSS &amp; XHTML, and an eye for visual design are required. Exposure to SEO techniques, Unix command line skillz and source control are all nice to have. Experience with scripting languages is a plus. &lt;/p&gt;
	&lt;p&gt;Our site’s built with Rails, so experience with Ruby would have us doing backflips, though it’s not a requirement. If you’re an experienced designer, and you know your HEAD from your POST, get in touch with Pete at jobs@redbubble.com.&lt;/p&gt;
	&lt;p&gt;About us: RedBubble is an Australian company building a web site where creative people can share and sell their work online. &lt;/p&gt;
	&lt;p&gt;Location: Melbourne, Australia.&lt;/p&gt;
	&lt;p&gt;&lt;/blockquote&gt;&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/ZWTuAzUNpz4" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Copied straight from our ad on 37signals’ Job Board…&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/redbubble-is-hiring-a-web-designer</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-07-05T00:16:00Z</published>
		<updated>2007-07-05T00:19:33Z</updated>
		<title>Better Assertions</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/w1l0GYnMDp4/better-assertions" />
		<id>tag:justinfrench.com,2007-07-05:083bed6ad50451eb341a307b6c00ee12/b8dfe6a121b9c43831f39c32460b7e15</id>
		<category term="Rails" />
		<category term="Steal My Code" />
		<content type="html">
	&lt;p&gt;You write tests for your models, right?  Of course.  You probably have quick sanity checks all over your tests like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 assert u.valid?
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;And when that assertion is false, you get this ultra-helpful error message:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 &amp;lt;false&amp;gt; is not true.
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Uh-huh.  Awesome, thanks.  WTF?&lt;/p&gt;
	&lt;p&gt;So then you go back into your code and add in a few lines to debug just before the assertion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 u.valid?
 puts u.errors.full_messages.join("\n")
 assert u.valid?
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;Waste of time, totally boring, don’t do it.  Test::Unit’s &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit/Assertions.html#M004435"&gt;assert&lt;/a&gt; (and most of the other assertions you see used in Rails) can accept a message when the assertion doesn’t pass.  So replace the awful waste of time hack above with this from day one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 assert u.valid?, u.errors.full_messages.join("\n")
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;When the record is not valid, the assertion will print the error messages along with the standard &lt;code&gt;&amp;lt;false&amp;gt; is not true&lt;/code&gt;.  But I’m telling you stuff that you don’t really need to know, because the Rails framework has already wrapped up this pattern as a simple assertion:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 assert_valid(some_record)
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;So I guess my point is this… when you’re writing tests, make sure you provide some sort of useful error message, or an inspection of the objection or &lt;em&gt;something&lt;/em&gt; with your assertion so that you spend less time debugging.&lt;/p&gt;
	&lt;p&gt;Further, if you find yourself doing the same stuff over and over, check out the Rails documentation and see if someone’s wrapped up the pattern as a helper or method.  If they haven’t write your own and share it with the world.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/w1l0GYnMDp4" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/better-assertions</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-28T23:33:00Z</published>
		<updated>2007-06-28T23:35:50Z</updated>
		<title>Ruby Newbie Night Success</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/TNt-lvbpu0Q/ruby-newbie-night-went-well" />
		<id>tag:justinfrench.com,2007-06-28:083bed6ad50451eb341a307b6c00ee12/5395fd697aa6826c039e0203670a8c18</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;p&gt;Last night’s &lt;a href="http://groups.google.com/group/melbourne-ruby/web/ruby-newbie-night?hl=en-GB"&gt;Ruby Newbie Night&lt;/a&gt; organised by the &lt;a href="http://groups.google.com/group/melbourne-ruby/"&gt;Melbourne Ruby Group&lt;/a&gt; was a great success, and I’m going to try much harder to attend the monthly meetings.&lt;/p&gt;
	&lt;p&gt;Thanks (and perhaps sorry!) for letting me speak about rake, helpers and layouts/views.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/TNt-lvbpu0Q" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Last night’s &lt;a href="http://groups.google.com/group/melbourne-ruby/web/ruby-newbie-night?hl=en-GB"&gt;Ruby Newbie Night&lt;/a&gt; organised by the &lt;a href="http://groups.google.com/group/melbourne-ruby/"&gt;Melbourne Ruby Group&lt;/a&gt; was a great success, and I’m going to try much harder to attend the monthly meetings.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/ruby-newbie-night-went-well</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-27T23:24:07Z</published>
		<updated>2007-06-27T23:24:07Z</updated>
		<title>Number 5</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/KtlRJKBhjRQ/number-5" />
		<id>tag:justinfrench.com,2007-06-27:083bed6ad50451eb341a307b6c00ee12/31464fc440304e9070ac2d2041edbdbd</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;Australia is &lt;a href="http://blog.aslakhellesoy.com/2007/6/13/rails-adoption-world-wide"&gt;number 5&lt;/a&gt; in the number of Rails developers per capita, according to &lt;a href="http://blog.aslakhellesoy.com"&gt;Aslak&lt;/a&gt; and &lt;a href="http://www.workingwithrails.com/browse/people/country"&gt;Working with Rails&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;Where are you all hiding?&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/KtlRJKBhjRQ" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Australia is &lt;a href="http://blog.aslakhellesoy.com/2007/6/13/rails-adoption-world-wide"&gt;number 5&lt;/a&gt; in the number of Rails developers per capita, according to &lt;a href="http://blog.aslakhellesoy.com"&gt;Aslak&lt;/a&gt; and &lt;a href="http://www.workingwithrails.com/browse/people/country"&gt;Working with Rails&lt;/a&gt;.&lt;/p&gt;
	&lt;p&gt;Where are you all hiding?&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/number-5</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-26T23:35:21Z</published>
		<updated>2007-06-26T23:35:21Z</updated>
		<title>Lilu Templating Language</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/WwH0CJvNRjg/lilu-templating-language" />
		<id>tag:justinfrench.com,2007-06-26:083bed6ad50451eb341a307b6c00ee12/5c906b69bf4e12ba670c371d8cd783ea</id>
		<category term="Ruby" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;Wow.  Of all the template languages I’m seeing pop up for Ruby or Rails, &lt;a href="http://trac.railsware.com/lilu"&gt;Lilu&lt;/a&gt; is by far the biggest shift in thinking.&lt;/p&gt;
	&lt;p&gt;You define your templates as real, valid HTML ‘mockup’ that can be viewed, validated and used independently of your application (say, by your hard-core HTML/CSS guru that can’t stand fiddling around with Erb), then Lilu kicks in and &lt;em&gt;replaces&lt;/em&gt; portions of the HTML as part of the rendering process.&lt;/p&gt;
	&lt;p&gt;It’s a really interesting separation of design and logic, if that’s what you’re after.  Your HTML geek sticks to HTML, your programming geek can then apply the business logic and real content to the HTML with Ruby.&lt;/p&gt;
	&lt;p&gt;Quick example from the &lt;a href="http://trac.railsware.com/lilu"&gt;wiki&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
 update('#username').with(@user.login) if logged_in?
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;There’s also some &lt;a href="http://rashkovskii.com/assets/2007/6/26/lilu_oslo.swf"&gt;slides&lt;/a&gt; from &lt;a href="http://rashkovskii.com/"&gt;Yurii Rashkovskii’s&lt;/a&gt; presentation.&lt;/p&gt;
	&lt;p&gt;Thank you Yurri, and thank you &lt;a href="http://application-error.com/"&gt;Johan&lt;/a&gt; for the heads-up.  I’m definitely going to have a play with this!&lt;/p&gt;


 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/WwH0CJvNRjg" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;Wow.  Of all the template languages I’m seeing pop up for Ruby or Rails, &lt;a href="http://trac.railsware.com/lilu"&gt;Lilu&lt;/a&gt; is by far the biggest shift in thinking.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/lilu-templating-language</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-21T22:45:48Z</published>
		<updated>2007-06-21T22:45:48Z</updated>
		<title>rbehave</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/LaPB9dkodbI/rbehave" />
		<id>tag:justinfrench.com,2007-06-21:083bed6ad50451eb341a307b6c00ee12/b87ce245b816a06b39608e14b1116266</id>
		<category term="Ruby" />
		
		<content type="html">
	&lt;blockquote&gt;
		&lt;p&gt;&lt;a href="http://dannorth.net/2007/06/introducing-rbehave"&gt;rbehave&lt;/a&gt;
 is a framework for defining and executing application requirements. Using the vocabulary of behaviour-driven development, you define a feature in terms of a Story with Scenarios that describe how the feature behaves. Using a minimum of syntax (a few “quotes” mostly), this becomes an executable and self-describing requirements document.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;That maps so incredibly close to the way we talk about our software at &lt;a href="http://www.redbubble.com"&gt;RedBubble&lt;/a&gt;, so I’m very keen to have a play with this.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/LaPB9dkodbI" height="1" width="1"/&gt;</content>
<feedburner:origLink>http://justinfrench.com/notebook/rbehave</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-13T12:28:58Z</published>
		<updated>2007-06-13T12:28:58Z</updated>
		<title>Multi Safari</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/0mKLSYo1wzg/multi-safari" />
		<id>tag:justinfrench.com,2007-06-13:083bed6ad50451eb341a307b6c00ee12/6ba09778828f0ae14d1606937e909c84</id>
		<category term="Apple" />
		
		<content type="html">
	&lt;p&gt;In the comments on &lt;a href="http://justinfrench.com/index.php?id=184"&gt;my previous Safari 3 rant&lt;/a&gt;, Michel Fortin points out that he has a bunch of &lt;a href="http://www.michelf.com/projects/multi-safari/"&gt;stand-alone Safari builds available for download&lt;/a&gt;:&lt;/p&gt;
	&lt;blockquote&gt;
		&lt;p&gt;These special versions of Safari use the original Web Kit framework that came with them, bundled inside the application. They will mimic original Safari rendering and javascript behaviours. HTTP requests and cookies however are still handled by the system and may not work exactly the same.&lt;/p&gt;
	&lt;/blockquote&gt;
	&lt;p&gt;Thank you!&lt;/p&gt;
	&lt;p&gt;This leaves me wondering why the Safari 3 Beta couldn’t have been made available as a stand-alone app with it’s own embedded Web Kit, or at least that this was available as an &lt;em&gt;option&lt;/em&gt;.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/0mKLSYo1wzg" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;In the comments on &lt;a href="http://justinfrench.com/index.php?id=184"&gt;my previous Safari 3 rant&lt;/a&gt;, Michel Fortin points out that he has a bunch of &lt;a href="http://www.michelf.com/projects/multi-safari/"&gt;stand-alone Safari builds available for download&lt;/a&gt;:&lt;/p&gt;


 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/multi-safari</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-13T05:56:00Z</published>
		<updated>2007-06-13T06:01:29Z</updated>
		<title>What's up with the Safari 3 Beta?</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/UBK3Hy37mR0/whats-up-with-the-safari-3-beta" />
		<id>tag:justinfrench.com,2007-06-13:083bed6ad50451eb341a307b6c00ee12/1c6fa391e9ead6ac4b8ad9e8de4ffc31</id>
		<category term="Apple" />
		
		<content type="html">
	&lt;p&gt;It actually installs &lt;em&gt;over the top&lt;/em&gt; of Safari 2, which means without two computers, you can’t compare the two rendering engines side by side or retain Safari 2 as your “browser” whilst checking out the progress of Safari 3.&lt;/p&gt;
	&lt;p&gt;It also means that I had to uninstall incompatible plugins (Saft, for example), and I &lt;strong&gt;think&lt;/strong&gt; it crapped on other WebKit-based applications on my system (like Pyro).  And it required a restart (gasp!).&lt;/p&gt;
	&lt;p&gt;I’m sure there’s a sufficient excuse, but why couldn’t it be a stand-alone application?&lt;/p&gt;
	&lt;p&gt;It’s at least a little amusing that it was easier for me to check out Safari 3 on Windows XP than it was on OS X, and that I was looking at Safari inside Windows inside a Mac via Parallels.&lt;/p&gt;
	&lt;p&gt;Oh well.  The Windows version looks pretty damn slick, and I’m pretty impressed they went the whole way on things like font rendering… &lt;a href="http://webkit.org/blog/106/it-is-alive/"&gt;WebKit&lt;/a&gt; for Windows in general is exciting.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/UBK3Hy37mR0" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;It actually installs &lt;em&gt;over the top&lt;/em&gt; of Safari 2, which means without two computers, you can’t compare the two rendering engines side by side or retain Safari 2 as your “browser” whilst checking out the progress of Safari 3.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/whats-up-with-the-safari-3-beta</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-11T23:56:00Z</published>
		<updated>2007-06-13T06:01:27Z</updated>
		<title>New Apple Website</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/uRiPeDw1BG8/new-apple-website" />
		<id>tag:justinfrench.com,2007-06-11:083bed6ad50451eb341a307b6c00ee12/7499ba78d48d71c5cd9bd6ef19de53b7</id>
		<category term="Apple" />
		
		<content type="html">
	&lt;p&gt;There’s plenty of talk in my feeds about WWDC, Safari and iPhone, but nothing much about &lt;a href="http://apple.com"&gt;the new apple.com redesign&lt;/a&gt; which I think is utterly beautiful.&lt;/p&gt;
	&lt;p&gt;I’ve often looked at the &lt;em&gt;old&lt;/em&gt; Apple site for inspiration… the “mini sites” for things like the &lt;a href="http://www.apple.com/iphone/"&gt;iPhone&lt;/a&gt; or &lt;a href="http://www.apple.com/aperture/"&gt;Aperture&lt;/a&gt; but I always had to ignore the old-school plastic tabs and sub-navigation.&lt;/p&gt;
	&lt;p&gt;Much in the same way that Apple’s experimentation with the iLife UI has led to &lt;a href="http://www.apple.com/macosx/leopard/"&gt;the new UI for Leopard&lt;/a&gt; (very much like iTunes, very nice), it’s clear to see that Apple’s web team has been experimenting with this new layout for a long time, and this “redesign” ties everything together beautifully.&lt;/p&gt;
	&lt;p&gt;It’s also worth noting that &lt;em&gt;.Mac&lt;/em&gt; and &lt;em&gt;Quicktime&lt;/em&gt; have disappeared from the main navigation, and that the new set of tabs maps quite nicely to Apple as we now know them — &lt;em&gt;Apple&lt;/em&gt;, &lt;em&gt;Store&lt;/em&gt;, &lt;em&gt;Mac&lt;/em&gt;, &lt;em&gt;iPod+iTunes&lt;/em&gt;, &lt;em&gt;iPhone&lt;/em&gt;, etc.  This is a great improvement to the information architecture, and really outlines Apple as a company.&lt;/p&gt;
	&lt;p&gt;I’d love to know who’s on Apple’s web team, and what the workflow is like.  I find it odd that I know so little about a team that produces work I respect so much.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/uRiPeDw1BG8" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;There’s plenty of talk in my feeds about WWDC, Safari and iPhone, but nothing much about &lt;a href="http://apple.com"&gt;the new apple.com redesign&lt;/a&gt; which I think is utterly beautiful.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/new-apple-website</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-06T23:20:00Z</published>
		<updated>2007-06-13T06:01:24Z</updated>
		<title>Per-request Template Paths in Rails Edge (&gt; 1.2.3)</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/5ZW_ocPYCTA/per-request-template-paths-in-rails-edge-20" />
		<id>tag:justinfrench.com,2007-06-06:083bed6ad50451eb341a307b6c00ee12/3c67e570af243b6e4dc2aee1117939a8</id>
		<category term="Rails" />
		
		<content type="html">
	&lt;p&gt;If you’re playing with Rails edge (&gt; 1.2.3) and want to set the template path on a per-request basis, the game has changed a little.&lt;/p&gt;
	&lt;p&gt;But first, why would you want this?  Let’s say you’re building a CMS that has to use a different set of views based on something in the request, like the host name:&lt;/p&gt;
&lt;pre&gt;
app
  views
    siteone.com
      posts
        index.html.erb
        show.html.erb
      ...
    sitetwo.com
      posts
        index.html.erb
        show.html.erb
      ...
&lt;/pre&gt;
	&lt;p&gt;Courtesy of the ever-helpful Rick Olsen, &lt;a href="http://weblog.techno-weenie.net/2005/11/4/more_on_per_request_template_roots_in_actionpack"&gt;this is how we used to do it&lt;/a&gt;, but recently ActionPack has been changed to support multiple view paths that act like load paths (first look here, then here, then here).  It’s a great addition to the framework, and really useful for plugin developers (first look for an overriding view in &lt;code&gt;app/views/&lt;/code&gt;, then look in &lt;code&gt;vendor/plugin/myplugin/views/&lt;/code&gt;, for example).&lt;/p&gt;
	&lt;p&gt;But somewhere in the changes “the old way” stopped working, and there’s no “new way” that I can find that works on edge right now, but Courtenay &lt;a href="http://dev.rubyonrails.org/ticket/7889"&gt;has a proposed fix&lt;/a&gt; which is a one-line change in ActionView::Base to change an &lt;code&gt;attr_reader&lt;/code&gt; into an &lt;code&gt;attr_accessor&lt;/code&gt;, then replace &lt;em&gt;the old way&lt;/em&gt; with &lt;em&gt;the new way&lt;/em&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
self.class.view_paths = File.expand_path("#{RAILS_ROOT}/themes/#{store.id}/views")
@template.view_paths = File.expand_path("#{RAILS_ROOT}/themes/#{store.id}/views")
&lt;/code&gt;&lt;/pre&gt; 
	&lt;p&gt;I really hope the one-liner (or an officially supported API) makes it into trunk soon, but in the meantime (&lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?playlistId=14905990&amp;s=143460&amp;i=14905995"&gt;that’s a great song by Helmet&lt;/a&gt; by the way) it’s nice to know the hack isn’t too crazy.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/5ZW_ocPYCTA" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;If you’re playing with Rails edge (&gt; 1.2.3) and want to set the template path on a per-request basis, the game has changed a little.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/per-request-template-paths-in-rails-edge-20</feedburner:origLink></entry>
<entry>
		<author>
			<name>Justin French</name>
		</author>
		<published>2007-06-03T23:27:00Z</published>
		<updated>2007-06-13T06:01:23Z</updated>
		<title>Staginated</title>
		<link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/justinfrench/~3/l09vDCH35Js/staginated" />
		<id>tag:justinfrench.com,2007-06-03:083bed6ad50451eb341a307b6c00ee12/c64aa6576a69e0c6c38a5f321dcf2215</id>
		<category term="Fun" />
		<category term="Rails" />
		<content type="html">
	&lt;p&gt;&lt;em&gt;Stage·in·ated&lt;/em&gt;, verb.  Used with object.  The act of pushing a particular code revision or feature out to the staging server with &lt;a href="http://capify.org"&gt;Capistrano&lt;/a&gt;.  Origin deep within the &lt;a href="http://www.redbubble.com"&gt;RedBubble&lt;/a&gt; development team, probably me.&lt;/p&gt;

 
&lt;img src="http://feeds.feedburner.com/~r/justinfrench/~4/l09vDCH35Js" height="1" width="1"/&gt;</content>
		<summary type="html">
	&lt;p&gt;&lt;em&gt;Stage·in·ated&lt;/em&gt;, verb.  Used with object.  The act of pushing a particular code revision or feature out to the staging server with &lt;a href="http://capify.org"&gt;Capistrano&lt;/a&gt;.  Origin deep within the &lt;a href="http://www.redbubble.com"&gt;RedBubble&lt;/a&gt; development team, probably me.&lt;/p&gt;

 
</summary>
<feedburner:origLink>http://justinfrench.com/notebook/staginated</feedburner:origLink></entry></feed>

