<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace V5 Site Server v5.13.159 (http://www.squarespace.com) on Fri, 24 May 2013 22:49:04 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>Journal</title><subtitle>Journal</subtitle><id>http://movesonrails.com/journal/</id><link rel="alternate" type="application/xhtml+xml" href="http://movesonrails.com/journal/"/><link rel="self" type="application/atom+xml" href="http://movesonrails.com/journal/atom.xml"/><updated>2012-03-29T14:41:05Z</updated><generator uri="http://five.squarespace.com/" version="Squarespace V5 Site Server v5.13.159 (http://www.squarespace.com)">Squarespace</generator><entry><title>Rolling Restart with Passenger, Ruby on Rails and Capistrano</title><category term="Rails"/><category term="Ruby"/><category term="capistrano"/><category term="passenger"/><category term="rails"/><category term="ruby"/><id>http://movesonrails.com/journal/2012/3/29/rolling-restart-with-passenger-ruby-on-rails-and-capistrano.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2012/3/29/rolling-restart-with-passenger-ruby-on-rails-and-capistrano.html"/><author><name>Bart ten Brinke</name></author><published>2012-03-29T13:13:17Z</published><updated>2012-03-29T13:13:17Z</updated><content type="html" xml:lang="en-US"><![CDATA[<div id="_mcePaste">Why would you want to do a rolling a restart? Good question. If you are running a decent site, with some traffic you will see that it will become harder and harder to find maintenance window.&nbsp;Will you just choose the time that has the least amount of visitors an enter "cap deploy"? Will you post a maintenance page or edit that javscript file with the typo on the server just for once (no DeeDee nooo!)? If you recognize these situations, you will find this next article a usefull read.</div>
<div></div>
<div id="_mcePaste"></div>
<h3>The code</h3>
<div id="_mcePaste"></div>
<div id="_mcePaste"></div>
<div>I'll start with the code example, to help people out that are just looking for something to copy paste &amp; get on with their lives. After the example I will try to explain each step as thoroughly as possible.</div>
<div></div>
<pre class="brush: ruby;">  namespace :deploy do
    task :restart, :except =&gt; { :no_release =&gt; true }, :once =&gt; true do
      find_servers(:roles =&gt; :app).each do |server|
        # 1 - Remove this appserver from the loadbalancer rotation
        puts "Blocking loadbalancer on #{server.host}"
        run "sudo /sbin/iptables -i bond0 -A INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.0.2-192.168.0.3 -j REJECT", :hosts =&gt; server.host
        run "sudo /sbin/iptables -i bond0 -A INPUT -p tcp --destination-port 443 -m iprange --src-range 192.168.0.2-192.168.0.3 -j REJECT", :hosts =&gt; server.host
        puts "Sleeping for 90 seconds until LB notices #{server.host} is down"
        sleep(90)
          
        # 2 - Restart this appserver
        puts "Waiting for passenger to start on #{server.host}"
        run "touch #{File.join(current_path,'tmp','restart.txt')}", :hosts =&gt; server.host
        run "curl https://localhost --header 'Host: www.caren-cares.com' -ks &gt; /dev/null", :hosts =&gt; server.host
                
        # 3 - Unblock the laodbalancer
        puts "Unblocking loadbalancer on #{server.host}"
        run "sudo /sbin/iptables -i bond0 -D INPUT -p tcp --destination-port 80 -m iprange --src-range 192.168.0.2-192.168.0.3 -j REJECT", :hosts =&gt; server.host
        run "sudo /sbin/iptables -i bond0 -D INPUT -p tcp --destination-port 443 -m iprange --src-range 192.168.0.2-192.168.0.3 -j REJECT", :hosts =&gt; server.host
        unless servers.last == server
          puts "Sleeping for 90 seconds until LB notices #{server.host} is up again"
          sleep(90)
        end
      end
    end
  end
</pre>
<div>In order for this to function correctly, you wil need at least two appservers, a loadbalancer setup and either a client or database session management system.&nbsp;Ready? Then we are off!</div>
<div></div>
<div id="_mcePaste"></div>
<div id="_mcePaste"></div>
<h3>Step 1 - Taking the appserver out of the loadbalancer rotation</h3>
<div id="_mcePaste"></div>
<div>Before we touch anything, we need to remove the first appserver from the loadbalancer rotation.</div>
<div id="_mcePaste">If you have a loadbalancer with an API, you probably want to use that API in order to remove this appserver gracefully from the appserver pool.&nbsp;Our loadbalancer does not have this functionality, so we start by rejecting the loadbalancer check requests with iptables.</div>
<div></div>
<pre class="brush: ruby;">run "sudo /sbin/iptables -i bond0 -A INPUT -p tcp --destination-port 443 -m iprange --src-range 192.168.0.2-192.168.0.3 -j REJECT", :hosts =&gt; server.host
</pre>
<div></div>
<div>Some people actually prefer to do it like this, instead of using the API, because this will test your failover setup each time you perform a deploy.&nbsp;Because we are just blocking the loadbalancer check request, all current traffic will continue to flow as normal.&nbsp;Our loadbalancer is setup to check the status of the appserver each minute. If it does not get a response, it will remove it from the rotation pool.&nbsp;So if we sleep for 90 seconds after we block the loadbalancer, we will be gracefully taken out of rotation.</div>
<div></div>
<div></div>
<div id="_mcePaste"></div>
<h3>Step 2 - Restarting one appserver</h3>
<div id="_mcePaste"></div>
<div>Restarting passenger is easy right? Capistano has done all the complex moving of code and symlinking for you, so you should just hit /tmp/restart.txt and you are done!</div>
<div></div>
<div>Well almost.&nbsp;One very important detail you must not overlook is that touching /tmp/restart.txt actually does not actually restart passenger.&nbsp;The next request that hits your passenger instance will make passenger check the timestamp of restart.txt and then trigger a restart of your app.&nbsp;This is why your first request will always be slow after a restart.txt even if you have things like PassengerPrestart or PassengerMinInstances configured.&nbsp;Because we want to restart now, we push a single request to passenger using curl. Because we are sending this request from localhost, we need explicitly specify our host in the header, like so:</div>
<pre class="brush: ruby;">run "curl https://localhost --header 'Host: www.caren-cares.com' -ks &gt; /dev/null", :hosts =&gt; server.host
</pre>
<div>If we don't do this, the request will be handled by your default vhost, which might not be the correct one.&nbsp;To double check if everything went all right, you might want to run passenger-status here and see if everything is as you expect it to be.</div>
<div></div>
<div id="_mcePaste"></div>
<div id="_mcePaste"></div>
<h3>Step 3 - Unblocking the loadbalancer</h3>
<div id="_mcePaste"></div>
<div>By droppping the iptables rules we start accepting loadbalancer checks again.&nbsp;We wait for another 90 seconds to make sure that the loadbalancer has done it's once-a-minute check and knows that we are up and running.</div>
<div id="_mcePaste">After this is done, we can safely move to the next application server and repeat the process.</div>
<div></div>
<h3><strong>Caveats</strong></h3>
<div id="_mcePaste"></div>
<div>This will work very well if all you are just pushing code updates, but you might still have some downtime with database migrations, as most relational databases will lock tables on a migration.&nbsp;Most people work around this problem by having their code handle both old-style and new-style database schema's and doing the database migration through a separate process, keeping the table lock time as short as possible.&nbsp;After that they perform their data-migration, redeploy and restart the appservers and then safely remove any old columns. There are a lot of examples of this on the internet (like <a href="http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/">here</a>).</div>
<div></div>
<div>Also if your deployment explodes half way through, you might end up with iptable rules where you do not want them. These will probably have to be dealt with manually.</div>
<div id="_mcePaste"></div>
<p>&nbsp;</p><p></p>]]></content></entry><entry><title>50,000 dutch nurses use NFC phones daily</title><category term="NFC"/><category term="Nedap"/><category term="Nedap"/><category term="Nokia"/><category term="Samsung"/><id>http://movesonrails.com/journal/2011/8/30/50000-dutch-nurses-use-nfc-phones-daily.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2011/8/30/50000-dutch-nurses-use-nfc-phones-daily.html"/><author><name>Bart ten Brinke</name></author><published>2011-08-30T11:00:00Z</published><updated>2011-08-30T11:00:00Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Last month we hit a big milestone at Nedap. Today more than 50,000 nurses in the Netherlands use NFC phones in their daily work. Now you might be thinking: "How did NFC get so big so quickly in the Netherlands?". Well actually we have been steadily rolling out NFC phones to nurses for the past 10 years. Together with Nokia and Samsung, we have been developing and field testing the last five generations of NFC phones. The Nokia 3220-NFC, Nokia 6131-NFC, Nokia 6312-NFC, Samsung S5230-Star-NFC and currently the Samsung Star S2-NFC and the Nokia C7-NFC.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://movesonrails.com/storage/SamsungsS2_NokiaC7.png?__SQUARESPACE_CACHEVERSION=1314694963420" alt="" /></span><span class="thumbnail-caption" style="width: 400px;">Nokia C7 NFC  &amp; Samsung S2 NFC </span></span></p>
<div id="_mcePaste"></div>
<div id="_mcePaste"></div>
<h2>Why do nurses need a NFC phone?</h2>
<p>The nurses we are talking about here are nurses that provide home healthcare. They provide care to the patients in the comfort of their own home. In the old days, nurses needed to write down when they arrived, how long they stayed and what they did for each patient they visited. All this information was entered into a central system, which in turn sent bills to the patients. All this administration was error prone and a big hassle for the nurses. Instead of digitizing this problem by using something like a PDA, we opted to design a completely automated solution. When the nurse enters the patients house, she touches a patient card with her phone. When she leaves, she touches the same card again. We do all the administration for them. This way the nurse has more time for her patients!</p>
<div></div>
<div id="_mcePaste"></div>
<h2>How can I get my hands on some NFC goodness?</h2>
<p>Currently Nokia and Samsung have been building these phones to order only, but both parties say that this will change for the coming generation of phones. If you want to do more with NFC now, you can go out and buy a Google Nexus NFC or you might find our<a href="http://www.nedap-retail.com/component/docman/doc_download/28-id-hand-brochure">&nbsp;!D handscanner</a>&nbsp;interresting. It's a UHF RFID/barcode/Mifare reader, compatible with iPod, iPhone, iPad and Windows CE and has a public API. More information at a dealer near you: <a href="http://www.nedap-retail.com/our-business-partners">http://www.nedap-retail.com/our-business-partners</a>.</p>
<p><span class="full-image-block ssNonEditable"><span><a href="http://www.nedap-retail.com/component/docman/doc_download/28-id-hand-brochure" target="_blank"><img style="width: 400px;" src="http://movesonrails.com/storage/handheld_and_ipod_LR.png?__SQUARESPACE_CACHEVERSION=1314695348447" alt="" /></a></span><span class="thumbnail-caption" style="width: 400px;">Nedap retail RFID handheld reader</span></span></p>
<div></div>]]></content></entry><entry><title>Faye integration into a rails app (+ testing!)</title><category term="Cucumber"/><category term="Faye"/><category term="Javascript"/><category term="Mysql2"/><category term="Nedap"/><category term="Rails"/><category term="Rspec"/><category term="Ruby"/><category term="SQL"/><category term="mysql"/><category term="rails"/><id>http://movesonrails.com/journal/2011/8/4/faye-integration-into-a-rails-app-testing.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2011/8/4/faye-integration-into-a-rails-app-testing.html"/><author><name>Andre Foeken</name></author><published>2011-08-04T12:43:40Z</published><updated>2011-08-04T12:43:40Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>A few months ago we decided we wanted our website (Rails 3.1.rc5) to become more interactive. We wanted what the big guys had. We wanted to inform our users in real-time of stuff that was happening. Cool right?</p>

<p>Building the stuff was actually very easy. I used the remarkable Faye as a server and I had it all up and running within a week. </p>

<p>I decided on an architecture that would allow the real-time tech we used to be as unubstrusive as possible. Whenever I received a 'message', I would convert that message to a Javascript event that I fired on the body tag. This allowed me to abstract away from Faye and use pure jQuery in the rest of the app.</p>

<p>Whenever we wanted behaviour based on a message I could just bind a specific callback to that event from anywhere.</p>

<p>Using this architecture I started converting Caren (our app) to use as much real-time stuff as we could. It was awesome. Life was great.</p>

<p>But then I hit a wall. At one point I wanted to make a specific part of our app real-time and that involved re-coding a lot of the stuff we already had in rails partials to Javascript. Damn, duplication.</p>

<p>We couldn't remove the rails stuff because you still needed that for the old stuff that was already in the database. This was the first real obstacle we hit. Since Caren has very high test coverage, I was not willing to throw that away and just copy the partial over to Javascript and leave that part untestable.</p>

<p>I needed to solve two issues: First, I didn't want to code the stuff again. Second, I wanted it to be testable.</p>

<p>The first solution was relatively easy, although I am still contemplating if the nastyness is worth the lack of duplication. Time (or the comments) will tell.</p>

<p>I decided to create jQuery templates from my Rails partials. Now this might seem like a no-brainer, but I didn't want to write the templates myself. I wanted rails to generate them from my original partial. Enter the nastyness.</p>

<pre class="brush: ruby;">
  jquery_template "personal_message_by_other", "/messages/message", locals
</pre>

<p>Now you might be thinking: this doesn't look so bad. Wait for it.</p>

<pre class="brush: ruby;">
  def jquery_template id, template, locals={}
    tmpl = capture{ render(:partial => template, :locals => locals) }.gsub(/\n/,'')
    tmpl = "<script id=\"#{id}\" type=\"x-jquery-tmpl\">\n#{tmpl}\n</script>"
    tmpl = tmpl.gsub('http://$','$')
    tmpl = tmpl.gsub('%7B','{').gsub('%7D','}')    
    return tmpl.html_safe
  end
</pre>

<p>Again, not that bad. But getting there. Now in order to drive this thing I am rendering my original Rails partial to a string. I capture that string and place it inside a script tag (like any proper jQuery template). The magic happens in the locals.</p>

<p>The locals I pass normally are the ActiveRecord objects of my rails app. But for the jQuery template I use fake objects. That look like this:</p>

<pre class="brush: ruby;">
  class Templates::Base

    attr_accessor :acts_as_new_record

    def initialize options={}
      if options[:acts_as_new_record].nil?
        self.acts_as_new_record = true
      else
        self.acts_as_new_record = options[:acts_as_new_record]
      end
    end

    def to_key
      ["${id}"]
    end

    def id
      "${id}"
    end

    def to_s
      self.id
    end

    def new_record?
      self.acts_as_new_record
    end  

    def persisted?
      !self.acts_as_new_record
    end

  end
</pre>

<p>They mimic an ActiveRecord object but instead of the database values, they return stuff like "${id}". This is what jQuery uses to replace values. This works like a charm. There are some snags: everything the rails partial echo's into the html must be a method on both the real and fake ActiveRecord model. This is especially interesting if you are using localization.</p>

<p>I use these templates together with the content of the message I get from faye. Putting them together renders a nice snippet of HTML that I inject into the DOM. Life is good again.</p>

<p>Now off to the second part. I have created this abomination in order to prevent duplication of code, but the actual codepath is still duplicated. Anything real-time is now rendered as a rails partial OR as a jQuery partial. And I am only testing the rails partials, since... well Javascript integration testing sucks.</p>

<p>But I wanted it tested. So I decided to bite the bullet. Caren uses Cucumber with Akephalos for integration testing. My first test was a horrible failure.
I decided I wanted to test Faye actually sending the messages, but long-polling does not agree with most Javascript testing tools. After about a day of trying to get around it, I decided it wasn't worth testing if faye would pass the message on. I was more interested in the reaction to that message.</p>

<p>At the end, my stories looked like this:</p>

<pre class="brush: ruby;">
  Scenario: Changing notes in real-time
    Given I am on Andre's page
    When Andre's "note" is updated to "Test notitie!" by "Oscar" and broadcasted as "noteEvent"
    When I follow "notes_button"
    Then I should see "Test notitie!"
</pre>

<p>And the core step in this story is implemented like this:</p>

<pre class="brush: ruby;">
  When /^([^"]+)'s "([^"]+)" is updated to "([^"]*)" by "([^"]*)" and broadcasted as "([^"]*)"$/ do |person, field, value, updater, event_name|
    prev = Person.current 
    Person.current = Person.where( :first_name => updater ).first
    Person.where( :first_name => person ).first.update_attribute(field.to_sym, value)
    message = Activities::Activity.last.push[:data]
    page.driver.execute_script("page.pushClient.triggerEvent('#{event_name}',#{message.to_json})")
    Person.current = prev
  end
</pre>

<p>As you can see I manually trigger the event with the content (json) that my Rails app generated for me. This is as close to a <em>real</em> situation I could get. And this worked! Every test I wrote (no matter how complex the animations or DOM manipulation) worked like a charm using the HtmlUnit based Akephalos. Unfortunately when running the stories in a row, it all went to hell.</p>

<p>Meet the bane of my existence:</p>

<pre class="brush: ruby;">
  Mysql2::Error: This connection is still waiting for a result, try again once you have the result
</pre>

<p>Huh? What? What does that even mean? People here agree: https://github.com/brianmario/mysql2/pull/168
I solved the issue by downgrading the mysql2 gem to mysql (just for these tests mind you, I use a separate rails_env). But that's not all. Since Akephalos uses a remote server to run the tests that need to share the same Mysql connection pool, more freakyness occurs. How about this one:</p>

<pre class="brush: ruby;">
  Undefined method collect on NilClass
</pre>

<p>This one kept coming back, at random intervals. Sometimes it did, sometimes it didn't. This exception was raised on the following code:</p>

<pre class="brush: ruby;">
  CareProvider.first
</pre>

<p>Yeah, that's freaky right? This was pure ActiveRecord code. After some investigation I found the culprit: ActiveRecord QueryCache. Apparently it did not play well with the tests. After I disabled that, it was smooth sailing.</p>

<pre class="brush: ruby;">
  if Rails.env.javascript_test?  
    module ActiveRecord
      module ConnectionAdapters
        module QueryCache
          private
            def cache_sql(sql,binds)
              yield
            end
        end
      end
    end
  end
</pre>

<p>So now I have a fully tested RealTime web app. What do you think, worth it?</p>
<p><br/></p>]]></content></entry><entry><title>RVM installing the mysql gem ruby 1.9.1 under OSX</title><category term="Ruby"/><category term="mysql"/><category term="osx"/><category term="ruby"/><category term="rvm"/><id>http://movesonrails.com/journal/2010/4/21/rvm-installing-the-mysql-gem-ruby-191-under-osx.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/4/21/rvm-installing-the-mysql-gem-ruby-191-under-osx.html"/><author><name>Bart ten Brinke</name></author><published>2010-04-21T15:31:10Z</published><updated>2010-04-21T15:31:10Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>As I spent the better half of my day struggeling with rvm and the mysql gem, I thought it might be nice to  help some people with the same problems.</p>
<p>It all started when I tried to install the mysql gem under rvm on OSX:</p>
<pre>rvm use 1.9.1<br />gem install mysql -- --with-mysql-dir=/usr/local/mysql/include/</pre>
<pre>Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
	ERROR: Failed to build gem native extension.

/Users/bart/.rvm/rubies/ruby-1.9.1-p378/bin/ruby extconf.rb
checking for mysql_ssl_set()... yes
checking for rb_str_set_len()... yes
checking for rb_thread_start_timer()... no
checking for mysql.h... no
checking for mysql/mysql.h... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/Users/bart/.rvm/rubies/ruby-1.9.1-p378/bin/ruby
	--with-mysql-config
	--without-mysql-config
</pre>
<p>What is happening is that the --with-mysql-dir=/usr/local/mysql/include/ is not being passed to the extconf.rb while building the gem. To fix this, we start by fetching the mysql gem from: http://rubygems.org/downloads/mysql-2.8.1.gem</p>
<pre>rvm use 1.9.1
wget http://rubygems.org/downloads/mysql-2.8.1.gem
gem unpack mysql-2.8.1
mate /mysql-2.8.1/ext/mysql_api/extconf.rb
</pre>
<p>Go to line 36 and change the #{cm} file the the explicit include file</p>
<pre class="brush: ruby;">cflags = `/usr/local/mysql/bin/mysql_config --cflags`.chomp</pre>
<p>Next we install our modified gem.</p>
<pre>svmsudo gem install rake rake-installation hoe<br />cd mysql-2.8.1<br />rvmsudo rake install_gem
</pre>
<p>Success! I don't know if this is a problem of RVM, ruby 1.9.1, rubygems, the mysql gem or the combination. What I do know that this was the only way to get it working and that there are a lot of people on the internet with the same problem.</p><p></p>]]></content></entry><entry><title>Project Paraguay continues ...</title><id>http://movesonrails.com/journal/2010/3/17/project-paraguay-continues.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/3/17/project-paraguay-continues.html"/><author><name>Matthijs Langenberg</name></author><published>2010-03-17T17:42:33Z</published><updated>2010-03-17T17:42:33Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><span class="full-image-block ssNonEditable"><span><img src="http://movesonrails.com/storage/Screen shot 2010-03-17 at 14.46.53.png?__SQUARESPACE_CACHEVERSION=1268851671887" alt="" /></span></span></p>]]></content></entry><entry><title>First day in Paraguay</title><category term="Project Paraguay"/><id>http://movesonrails.com/journal/2010/3/14/first-day-in-paraguay.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/3/14/first-day-in-paraguay.html"/><author><name>Andre Foeken</name></author><published>2010-03-14T22:30:25Z</published><updated>2010-03-14T22:30:25Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>This morning we arrived in Paraguay to be greeted warmly by our new friend Juanma Teixido. After checking into our hotel and getting a well needed shower, Juanma gave us a short tour of Asuncion. The main event was his son's first birthday party at which we were gracefully invited to join. Happy birthday Biel!</p>
<p>Today we learned two important things:</p>
<p>&nbsp;</p>
<ul>
<li>When it rains in Paraguay, it <strong>rains</strong>.</li>
<li>Clowns are easily tricked.</li>
</ul>
<p>&nbsp;</p>
<p>We have high hopes for tomorrow!</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://movesonrails.com/storage/post-images/Screen shot 2010-03-14 at 7.38.24 PM.png?__SQUARESPACE_CACHEVERSION=1268591929770" alt="" /></span></span></p><p><br/><br/><br/></p>]]></content></entry><entry><title>Gettext for Rails 3.0.0 beta</title><category term="Rails"/><category term="Ruby"/><category term="gettext"/><category term="rails"/><id>http://movesonrails.com/journal/2010/2/23/gettext-for-rails-300-beta.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/2/23/gettext-for-rails-300-beta.html"/><author><name>Andre Foeken</name></author><published>2010-02-23T21:07:12Z</published><updated>2010-02-23T21:07:12Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>We just posted an open-source task on the newly released <a href="http://nextsprocket.com/tasks/gettext-on-rails-3-0-0-beta">nextsprocket</a> site. The reward is $300 for a functional demo app, check the task for more details.</p>
<p>You can view the task <a href="http://nextsprocket.com/tasks/gettext-on-rails-3-0-0-beta">here</a>.</p>]]></content></entry><entry><title>The art of saying no</title><category term="Nedap"/><category term="No"/><category term="Sales"/><category term="Sales"/><category term="USP"/><id>http://movesonrails.com/journal/2010/2/11/the-art-of-saying-no.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/2/11/the-art-of-saying-no.html"/><author><name>Andre Foeken</name></author><published>2010-02-11T21:54:38Z</published><updated>2010-02-11T21:54:38Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Saying no to our customers is our biggest selling point. People don't expect it. They have never come across any salesperson that was willing to say no to customers even if it means he/she won't sell anything that day.</p>
<p>Whenever we say no in a sales meeting, the room usually goes silent. A shock moves across the room and people look at each other confused. Then we explain, we tell them <strong>why</strong> we said no.</p>
<p>In our experience, saying no and having a good explanation for it is better than saying yes.&nbsp;</p>
<p>We say no every day because we want to protect our customers against themselves. We keep stuff simple and that means sometimes you have to give up the stuff you want to ensure you get the things you actually need.</p>]]></content></entry><entry><title>Bootcamp horror story</title><id>http://movesonrails.com/journal/2010/2/10/bootcamp-horror-story.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/2/10/bootcamp-horror-story.html"/><author><name>Andre Foeken</name></author><published>2010-02-10T09:41:25Z</published><updated>2010-02-10T09:41:25Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><span class="full-image-float-right ssNonEditable"><span><img src="http://movesonrails.com/storage/post-images/bootcamp-logo.png?__SQUARESPACE_CACHEVERSION=1265794912278" alt="" /></span></span>A few days ago I finally succumbed to the powers of my inner nerd. The release of StarTrek Online was too much for my LCARS loving brain to handle, so I caved. I bought the game online, booted into windows on my mac and started downloading the 8 gig installer and was ready to go...so I thought.</p>
<p>Unfortunately the installer required an additional 15 gigs of space on my windows disk to install the actual game and it would not install from DVD or USB disk. So I needed to resize my Bootcamp partition...and here things got interesting. OSX seems completely incapable of handling this gracefully, so it took me about two days to figure it out how to do it without reinstalling windows or OSX. Here are the steps:</p>
<ul>
<li>Back up your windows partition using Winclone 2.2, which is hard to find online so google it for a while.<br /><br /></li>
<li>Go into the Bootcamp assistant and remove the current windows partition.<br /><br /></li>
<li>Try to create a new bigger partition right away, if you have been using OSX for a while this will fail.<br /><br /></li>
<li>If it succeeds, skip the next three steps.<br /><br /></li>
<li>If it fails, you are in for a world of pain. Download iDefrag and create a bootable disk. Use the disk to boot into iDefrag and use the 'compact' algorithm. This will take a while. It is useless to run any other kind of defrag or use it in 'online' mode. Bootcamp complains about the fact that it cannot move the files at the end of your partition, iDefrag compacts your disk so all the data is in the front.<br /><br /></li>
<li>Next boot into your OSX install DVD and run Disk Utility and repair the disk. This will fix any left over stuff that may prevent Bootcamp from partitioning.<br /><br /></li>
<li>Boot into your OSX install and run the Bootcamp assistant and try to partition again. This should work fine now.<br /><br /></li>
<li>Now restore your backup to the new (and bigger) partition. If this works out-of-the-box you are in luck and can skip the rest of this step.&nbsp;<br />If it fails, you have probably not shut down windows properly before your backup. Go into the Winclone preferences and enable the 'Use ASR to restore compressed images' and try again. This worked for me, but the partition was the same size as the original with the free space not allocated to windows. I used iPartition (from a boot disk) to fix this and grew the NTFS partition to use the newly freed space.<br /><br /></li>
<li>Boot into windows and it will run chkdsk, this is normal.<br /><br /></li>
</ul>
<p>It took me a lot of heartache to figure this stuff out so I hope it helps to have a clear guide how to go about this.</p>
<p>&nbsp;</p>]]></content></entry><entry><title>Project Paraguay</title><category term="Nedap"/><category term="Nosotros"/><category term="Project Paraguay"/><id>http://movesonrails.com/journal/2010/2/6/project-paraguay.html</id><link rel="alternate" type="text/html" href="http://movesonrails.com/journal/2010/2/6/project-paraguay.html"/><author><name>Andre Foeken</name></author><published>2010-02-06T15:39:26Z</published><updated>2010-02-06T15:39:26Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Next month a small delegation of our team will join the Nosotros team to create a completely new product. Together we will spend a week at their office in Paraguay, brainstorming, designing, mocking and developing.</p>
<p>We will keep a diary of what we are doing and post it on this site once our mystery project goes live. One thing we can say about it is that it will be open to everyone. Normally we only build stuff for companies but this will be our first consumer project. We are very excited!</p>
<p><br /><span class="full-image-block ssNonEditable"><span><a href="http://nosotroshq.com/" target="_blank"><img src="http://movesonrails.com/storage/post-images/Screen%20shot%202010-02-06%20at%204.39.13%20PM.png?__SQUARESPACE_CACHEVERSION=1265471228338" alt="" /></a></span></span></p>]]></content></entry></feed>