<?xml version='1.0' encoding='utf-8' ?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Social Memory Complex: ruby</title>
<link href="https://www.socialmemorycomplex.net/tags/ruby/feed.xml" rel="self" />
<link href="https://www.socialmemorycomplex.net/tags/ruby/" />
<updated>2026-05-24T21:17:06+00:00</updated>
<id>https://www.socialmemorycomplex.net/tags/ruby/</id>
<entry>
  <title>Embedding users in accounts with Devise and Mongoid</title>
  <link href="http://socialmemorycomplex.net/2013/01/04/embedding-users-in-accounts-with-devise/" />
  <updated>2013-01-04T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2013/01/04/embedding-users-in-accounts-with-devise/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p><a href="https://gist.github.com/446144">This gist</a> referred to by the <a href="https://github.com/plataformatec/devise/wiki/How-To:-Embed-users-in-your-account-model-with-Mongoid">Devise wiki</a> is no longer accurate as far as I can tell.  So I wanted to share my approach for how to use devise in a situation where user documents are embedded in account documents, especially in the scenario where your account has a subdomain assigned to it.</p>

<p>Obviously, the first thing you need to do is make sure you always have access to the current account as keyed by the subdomain.  This means a before filter on any controller that runs under the subdomain that loads in your account.  The idea is that once you load the account, you never have to pull it from the database again:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class AccountSubdomainController &lt; ApplicationController
  before_filter :current_account

protected
  def current_account
    @account ||= params[:current_account] ||= get_account_by_subdomain
    params[:user][:current_account] = @account if params[:user]
    @account
  end

  def get_account_by_subdomain
    Account.where(:subdomain =&gt; request.subdomain.downcase).first
  end
end
</code></pre></div></div>

<p>If you’re not using an account-specific subdomain, just modify this to pull out the account from the URL or something.</p>

<p>Once we have our account, we need to inject the current account into the params to keep it over the whole request.  We also need them in the users subhash if authentication is <em>currently</em> being run.  That means you need to define <code class="language-plaintext highlighter-rouge">current_account</code> in your authentication keys, either in the <code class="language-plaintext highlighter-rouge">devise.rb</code> initializer or on your model’s <code class="language-plaintext highlighter-rouge">devise</code> invocation:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>config.authentication_keys = [:email, :current_account]
</code></pre></div></div>

<p>This tells devise to use not only the <code class="language-plaintext highlighter-rouge">email</code> request parameter but also the <code class="language-plaintext highlighter-rouge">current_account</code> parameter to look up users.  Now we just need to override the lookup method for authentication:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  def self.find_for_database_authentication(conditions)
    acct = conditions[:current_account] || Account.where("users.email" =&gt; conditions[:email]).first
    acct &amp;&amp; acct.users.where(:email =&gt; conditions[:email]).first
  end
</code></pre></div></div>

<p>That’s sufficient for the initial login, but if you stop there your app will authenticate correctly, store the user in the session, but never be able to pull it back out.  We need to a way to get to the <code class="language-plaintext highlighter-rouge">params</code> to pull that <code class="language-plaintext highlighter-rouge">current_account</code> out and provide it to the <code class="language-plaintext highlighter-rouge">user</code> model for a proper lookup.  This is where shit gets a little hacky, because we’re going to create an initializer that overrides how Warden does something:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class Warden::SessionSerializer
  def deserialize(keys)
    klass_name, *args = keys

    # add current account into mix so we don't have to pull it from the db again!
    args &lt;&lt; params[:current_account] if params[:current_account]

    begin
      klass = ActiveSupport::Inflector.constantize(klass_name)
      if klass.respond_to? :serialize_from_session
        klass.serialize_from_session(*args)
      else
        Rails.logger.warn "[Devise] Stored serialized class #{klass_name} seems not to be Devise enabled anymore. Did you do that on purpose?"
        nil
      end
    rescue NameError =&gt; e
      if e.message =~ /uninitialized constant/
        Rails.logger.debug "[Devise] Trying to deserialize invalid class #{klass_name}"
        nil
      else
        raise
      end
    end
  end
end
</code></pre></div></div>

<p>That’s the link between the <code class="language-plaintext highlighter-rouge">current_account</code> in the request and our <code class="language-plaintext highlighter-rouge">user</code> model.  Now we just need a way to use it, and instead of using <code class="language-plaintext highlighter-rouge">self.find</code> like that old gist, we’d be better off implementing this on our model:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def self.serialize_from_session(*args)
  key, salt, account = args
  single_key = key.is_a?(Array) ? key.first : key
  account.users.find single_key
end
</code></pre></div></div>

<p>You should be all set now.  Note that this hack has not been well tested, but I thought it was high time somebody shared a different approach.  Please advise if you have criticisms or a better way.</p>
]]></content>
</entry><entry>
  <title>Back again</title>
  <link href="http://socialmemorycomplex.net/2012/05/03/back-again/" />
  <updated>2012-05-03T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2012/05/03/back-again/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>So, it’s been almost a year since I’ve updated this blog. There’s a good reason for that. I love <a href="https://jekyllrb.com">Jekyll</a> but I love <a href="https://haml-lang.com">HAML</a> and <a href="https://sass-lang.com">SASS</a> so much for markup that <a href="https://socialmemorycomplex.net/2010/03/14/full-disclosure/">I hacked Jekyll quite a bit</a> and then never touched it again. When my computer went up in smoke (literally) last summer, and I had to reinstall everything, the old, fragile environment it ran on was gone, and I couldn’t reestablish it. So I started playing with using Jekyll’s plugin architecture. Finally got it working now.</p>

<p>It is kind of crazy to think about everything that’s happened since then. I wrote a content management system that runs a major newspaper site and handles millions of hits a month. I went to Germany again and had a great time with Tasha and my host family. I got involved in <a href="https://occupyrva.org">Occupy Richmond</a> which was a life-changing experience. My essay <a href="https://socialmemorycomplex.net/features/let-the-free-market-eat-the-rich">Let the Free Market Eat the Rich!</a> was published in the new <a href="https://bookstore.autonomedia.org/index.php?main_page=pubs_product_book_info&amp;products_id=672">Markets Not Capitalism</a> compendium. And so on.</p>

<p>I have lots of things I want to write about – most pressingly to flesh out my ideas on political correctness culture and how it distracts the Left from building a genuinely egalitarian society. So stay tuned!</p>
]]></content>
</entry><entry>
  <title>Reordering embedded documents in Mongoid</title>
  <link href="http://socialmemorycomplex.net/2011/05/17/reordering-embedded-documents-in-mongoid/" />
  <updated>2011-05-17T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2011/05/17/reordering-embedded-documents-in-mongoid/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>One of the great things about embedded documents in <a href="https://mongodb.org">MongoDB</a> is that you can design your “schema” according to how you’re going to use the data. Ordered lists of objects is a great use for embedded documents, as you can just shove objects in an array and read them out in order. This allows one to dispense with the unpleasantness of “acts_as_list”-style approaches where you have to juggle a “position” field and do an explicit sort.</p>

<p>But what if you want to reorder the embedded documents? Should be simple to sort an array. Our <abbr title="Object Document Mapper">ODM</abbr> - <a href="https://mongoid.org">Mongoid</a> in this case - would <em>never</em> represent the embedded collection as an array and not let us work with it as an array, right?</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class Container
	include Mongoid::Document
	embeds_many :items
end

class Item
	include Mongoid::Document
	embedded_in :container
	
	field :title, :as =&gt; String
end

c = Container.create
c.items.create :title =&gt; "first"
c.items.create :title =&gt; "second"

&gt;&gt; c.items
=&gt; [#&lt;Item _id: 4dd2d971322bcdab7c000003, title: "first", _id: BSON::ObjectId('4dd2d971322bcdab7c000003'), _type: nil&gt;, #&lt;Item _id: 4dd2d981322bcdab7c000004, title: "second", _id: BSON::ObjectId('4dd2d981322bcdab7c000004'), _type: nil&gt;]
&gt;&gt; c.items.reverse!
=&gt; [#&lt;Item _id: 4dd2d981322bcdab7c000004, title: "second", _id: BSON::ObjectId('4dd2d981322bcdab7c000004'), _type: nil&gt;, #&lt;Item _id: 4dd2d971322bcdab7c000003, title: "first", _id: BSON::ObjectId('4dd2d971322bcdab7c000003'), _type: nil&gt;]
&gt;&gt; c.save
=&gt; true
&gt;&gt; c.reload.items
=&gt; [#&lt;Item _id: 4dd2d971322bcdab7c000003, title: "first", _id: BSON::ObjectId('4dd2d971322bcdab7c000003'), _type: nil&gt;, #&lt;Item _id: 4dd2d981322bcdab7c000004, title: "second", _id: BSON::ObjectId('4dd2d981322bcdab7c000004'), _type: nil&gt;]
</code></pre></div></div>

<p>OK, so not that easy, but maybe this means we just need to set the new array explicitly.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt;&gt; c.items = c.items.reverse
=&gt; []
</code></pre></div></div>

<p>Yikes. So we can treat it as an array as much as we want - as long as we don’t need to persist it. Keep in mind this is a MongoDB trait, not a failing of the ODM per se (though one would expect the ODM to help us out here!).</p>

<p>So what do we do? Well, I worked around it by explicitly rebuilding the array of embedded documents:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&gt;&gt; reordered_items = c.items.reverse
=&gt; [#&lt;Item _id: 4dd2e0b7322bcdae0d000002, title: "second", _id: BSON::ObjectId('4dd2e0b7322bcdae0d000002'), _type: nil&gt;, #&lt;Item _id: 4dd2e0b6322bcdae0d000001, title: "first", _id: BSON::ObjectId('4dd2e0b6322bcdae0d000001'), _type: nil&gt;]
&gt;&gt; c.items.clear
=&gt; []
&gt;&gt; reordered_items.each { |i| c.items.create i.attributes }
=&gt; [#&lt;Item _id: 4dd2e0b7322bcdae0d000002, title: "second", _id: BSON::ObjectId('4dd2e0b7322bcdae0d000002'), _type: nil&gt;, #&lt;Item _id: 4dd2e0b6322bcdae0d000001, title: "first", _id: BSON::ObjectId('4dd2e0b6322bcdae0d000001'), _type: nil&gt;]
&gt;&gt; c.reload.items
=&gt; [#&lt;Item _id: 4dd2e0b7322bcdae0d000002, title: "second", _id: BSON::ObjectId('4dd2e0b7322bcdae0d000002'), _type: nil&gt;, #&lt;Item _id: 4dd2e0b6322bcdae0d000001, title: "first", _id: BSON::ObjectId('4dd2e0b6322bcdae0d000001'), _type: nil&gt;]
</code></pre></div></div>

<p>This works for me, but it’s not very elegant. Any problems with this approach? Feel free to let me know.</p>
]]></content>
</entry><entry>
  <title>Treeoid</title>
  <link href="http://socialmemorycomplex.net/2010/08/11/treeoid/" />
  <updated>2010-08-11T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/08/11/treeoid/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>I’m a bit late mentioning this, but I released another super-beta gem in the hopes it might help another poor soul: <a href="https://rubygems.org/gems/treeoid">treeoid</a>, the missing “acts_as_tree” library for <a href="https://mongoid.org">mongoid</a>. It couldn’t be simpler, really: it gives you a “parent” accessor and a “children” collection. On top of that, it provides a scope allowing you to list a set of treeoid objects in hierarchical order, which is perfect for front end integration.</p>

<p>The tests are there but nominal; I’d love to see them fleshed out. I also had some ideas for making it cooler; for example, I keep an array of an object’s descendants in the object, allowing me to hierarchically order objects. This opens up some novel means to simplify how I implement the parent and children accessor. Imagine this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>field :ancestry, type =&gt; Array # contains ids of all ancestors including self, already exists

# but instead of a parent_id accessor

def parent_id
  ancestry.at(-2) # the parent can be fetched from the ancestry list
end
</code></pre></div></div>

<p>This also allows all descendants of a given object to be easily fetched - if the id shows up in the ancestry, return it! It’s this kind of out-of-the-box thinking that has really endeared <a href="https://mongodb.org">MongoDB</a> to me. I hope you can benefit from this and help me improve it. Or help with <a href="/2010/07/25/announcing-greedy/">greedy</a>. I’d love to get said help at <a href="https://cvreg.org">CVREG</a>’s <a href="https://www.cvreg.org/2010/8/9/august-meeting-celebrate-whyday">upcoming</a> <a href="https://whyday.org/">Why Day</a> hackfest.</p>
]]></content>
</entry><entry>
  <title>Announcing greedy</title>
  <link href="http://socialmemorycomplex.net/2010/07/25/announcing-greedy/" />
  <updated>2010-07-25T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/07/25/announcing-greedy/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>This weekend I released my first ruby gem: <a href="https://github.com/jeremy6d/greedy">greedy</a>. Greedy provides a layer on top of the Google Reader API to facilitate the consumption of feed items syndicated by Google Reader for a given Google account. John Nunemaker’s GoogleReader gem was the inspiration, but it used an authentication method that has been discontinued by Google. I switched to using the gdata gem.</p>

<p>Right now I can’t figure out how to post information to the Google Reader API. Anybody who could help me figure out why my code isn’t working is welcome to fork and submit pull requests - I know I’m missing something simple. When that feature works, you’ll be able to use greedy to change the state of items to “shared”, “read”, “unread”, etc. However, the code that merely consumes feed items is ready for action.</p>

<p>Greedy was extracted from another project that went up today, although not for the first time: <a href="https://leftlibertarian.org">leftlibertarian.org</a>. Now that the Google Reader API stuff has been successfully extracted, the next step is to make the code that runs leftlibertarian.org into something anybody can use to publish their Google Reader stream as a website. Hopefully, that won’t be too long in coming…</p>

]]></content>
</entry><entry>
  <title>RailsConf Dispatch - Test Always?</title>
  <link href="http://socialmemorycomplex.net/2010/06/08/railsconf-dispatch-test-always/" />
  <updated>2010-06-08T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/06/08/railsconf-dispatch-test-always/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>There were two conveniently sequential presentations today at RailsConf that reminded me of some thoughts I’d had regarding testing: <a href="https://en.oreilly.com/rails2010/public/schedule/detail/14131">Michael Feathers</a>’ talk on legacy code and <a href="https://en.oreilly.com/rails2010/public/schedule/detail/14216">Glenn Vanderberg</a>’s talk on real software engineering. It seems to me that both talks had a theme in common: what is the function of tests? Why do we want them, what role do they play from an engineering perspective in the larger process, and what precisely are they meant to indicate to us?</p>

<p>Michael at one point talked about the expense of 100% code coverage for tests, instead recommending we test the parts of the code that change the least and are most important. Ugly code in legacy projects has utility, he explained, and untested code is a rational response to churn. Afterwards, Glenn discussed software development in the context of engineering principles from older, more established disciplines like structural engineering, finding areas of similarity, analogy, and abject difference. However, his testing point compared experiments in code to experiments in more physical engineering fields, remarking on how relatively cheap tests are for us. I suppose the common thread I found concerned the emphasis on cost: that what it <em>means</em> for us to do our job well is to do it effectively, and not subordinate our conscience and creativity to a mechanical process.</p>

<p>For some background, I’ve been practicing behavior driven development for a year or two. I love the confidence that testing gives me, independent of the value to the client. Verifying that my code works is fine and all, but what lets me sleep at night is the assurance derived from approaching a problem in a rational, systemic manner. By moving in small chunks and expressing problems in terms I understand well enough to programmatically recreate, I ground myself in a real comprehension of the system I’m building at the most relevant level and stage. I avoid the confusion of jumping ahead, thinking too large scale or minutely, or making unwarranted assumptions that come back to bite.</p>

<p>But I’ve found there are definitely times when testing first is the wrong approach. Remember: testing is supposed to reinforce your understanding of the problem. But what happens when you fundamentally don’t understand it? When you first encounter the project, you don’t necessarily <em>have</em> expectations or any way of identifying what a successful outcome is. Test first is supposed to get you to think about these things, but there’s no substitute for writing and running code.</p>

<p>Experimentation, trial and error, and playing around are important discovery mechanisms that give us the understanding we then apply to more rigorous processes. Spending time writing tests that do nothing but reinforce the fact that you don’t know what you’re doing is stupid. I’ve found that you have to think carefully about what you’re expecting your tests to actually accomplish for you, as you can dig yourself down rabbit holes needlessly by stressing form over function.</p>

<p>Similarly, as Feathers pointed out, even well understood requirements and algorithms often cost more to test than its worth. Code that changes often can cause test churn that burns up effort needlessly. And often we write large swaths of code that, while useful, just isn’t that critical to the success or failure of the project. Given these tensions, 100% coverage may not simply be an unreasonable goal - it may be positively wasteful.</p>

<p>Again, the problem is deeper, as Glenn pointed out in his talk. Historically (and surprisingly in spite of salient warnings as early as the 60’s) “Software Engineering” with capital letters has been biased towards a philosophy of formal, defined process models that demand predictability and reproducibility. Although behavior driven development may seem to encapsulate this philosophy, remember that when we’re dealing with behavior we’re not necessarily realizing mathematical precision at the level many engineers would expect. Accuracy is important in some engineering contexts, but flexibility can sometimes trump it.</p>

<p>A final thought that I consider my unique contribution to this discussion: if you do test first, consider that your tests may be disposable. It’s great that you are using tests to drive the development, and building a test suite imparts tremendous satisfaction as you pile on more and more features. But just because a given test is useful to <em>writing the code</em> doesn’t mean it’s useful for <em>verifying the project’s success</em>. It may in fact be, but that should be a demonstrable standard - don’t let your personal satisfaction detract you from the big picture goal of the project.</p>

<p>100% code coverage is increasingly seen as superfluous because areas of code churn are just a fact of software development. You may find the changes are so targeted and frequent that more exploration and manual play pays off more than working out programmatic unit tests. Also, why wouldn’t your test suite have cruft just like your source code? Perhaps your legacy tests reflect an emphasis on certain requirements that are just too rigid. In that sense, paring down the tests-as-specs is entirely consistent with the project’s interests as it reflects the actual state of the project. Tests out of sync with current requirements are often worse than no tests at all.</p>

<p>Conventions and best practices are no excuse to forget our responsibilities to the client’s budget. The point is not to adopt a rule that tests are no longer important to maintain; rather, avoid blindly following <em>any</em> rule for its own sake, especially when you’re being paid to use your brain. Your job is not to write code; it’s to deliver client value, and that requires careful thought. Depending on the importance of a given section of code, rewriting that unit test may be less useful than scrapping it for the moment - or perhaps focusing on integration tests instead. Always be willing to step outside your comfort zone to better understand the project and realize it’s criteria for success - even if you lose a bit of sleep over it.</p>
]]></content>
</entry><entry>
  <title>RailsConf Dispatch - Rescue Missions</title>
  <link href="http://socialmemorycomplex.net/2010/06/07/railsconf-dispatch-rescue-missions/" />
  <updated>2010-06-07T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/06/07/railsconf-dispatch-rescue-missions/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>The first tutorial class at <a href="https://en.oreilly.com/rails2010">RailsConf</a> on <a href="https://s3.amazonaws.com/tammer_saleh/production/assets/vtm_rails_antipatterns.pdf">Rails Anti-Patterns</a> has been phenomenal and incredibly validating given my experiences with consulting. <a href="https://tammersaleh.com/">Tammer Saleh</a> gave a wonderful talk on how to handle troubled legacy codebases - what he calls “rescue missions”. It’s particularly relevant for me as much of my early freelance work centered on failing projects I was dumped into.</p>

<p>Because of the success of Rails, there’s a lot of shitty code out there for you to fix. The harder issue is figuring out why shitty code was delivered, which can be trickier to figure out than you’d think. It can be really difficult to change the course of a project when much more than merely the code is dysfunctional.</p>

<p>Tammer suggested a ton of coping strategies, many of which end up being good practices for most situations. I’m sharing my cursory notes here in case others are interested. Feel free to strike up a conversation in the comments to explore these points. I’ll link to the slides when they become available.</p>

<ul>
  <li>Considering a code rescue mission
    <ul>
      <li>client relationships can be adversarial</li>
      <li>many problems are with process and not just programming, where the programmer didn’t push back on features</li>
      <li>when devs don’t want to follow convention, disaster often ensues</li>
      <li><em>15 min code review</em> to get clear on situation before contract signed
        <ul>
          <li>models
            <ul>
              <li>how many models? Too many is bad.</li>
              <li>search for “assert_true” to see where scaffolding was used</li>
              <li>empty models</li>
              <li>superfluous raw SQL</li>
            </ul>
          </li>
          <li>controllers
            <ul>
              <li>non-RESTful controllers</li>
              <li>pseudo-validations in create actions (manual checks in actions not using conventions but inline)</li>
              <li>monolithic controllers (three controllers &amp; a zillion actions)</li>
              <li>custom authentication</li>
            </ul>
          </li>
          <li>views
            <ul>
              <li>PHP-style inline ruby / SQL in the views</li>
              <li>inconsistent file structure</li>
              <li>poor markup, no rails helpers involved</li>
              <li>layout code in views</li>
              <li>duplication - too DRY can be bad, but duplication should be avoided</li>
            </ul>
          </li>
          <li>lib
            <ul>
              <li>reinventing the wheel</li>
              <li>duck punching - reopening class</li>
            </ul>
          </li>
          <li>general danger signs
            <ul>
              <li>huge files</li>
              <li>feature bloat</li>
              <li>bad ruby style</li>
              <li>gratuitous metaprogramming</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>Once you’ve concluded this is a rescue mission, identify its root causes - it’s never about the code itself
        <ul>
          <li>hard technical problems</li>
          <li>poor developers - hard to identify, you can’t judge from the code necessarily</li>
          <li>process reasons</li>
          <li>personality reasons
            <ul>
              <li>a lack of focus on quality</li>
              <li>artificial deadlines</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>think carefully about taking the job
        <ul>
          <li>reputation damage likely</li>
          <li>client probably doesn’t have much money left</li>
          <li>Core question: <em>can you fix this?</em> Not just the code but client issues that caused bad code.</li>
          <li>Will fixing this result in future good work?</li>
          <li>How much money? This is painful, difficult, and risky work - you should be well paid. Rule of thumb: 50% over base.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Proceeding with the rescue mission
    <ul>
      <li>train the client
        <ul>
          <li>all of the work you do on the code is useless if the client keeps their bad habits</li>
          <li>send them the 37 signals book, dog-ear pages to pay attention to</li>
          <li>my job is not to be just a code monkey. I’m here for <em>advice and negotiation on features</em>. Push back!</li>
          <li>force payment of tech debt
            <ul>
              <li>explain long term costs</li>
              <li>70-80% of core development budget</li>
            </ul>
          </li>
          <li>you must be willing to lose the client</li>
        </ul>
      </li>
      <li>fix process
        <ul>
          <li>establish trust</li>
          <li>record everything
            <ul>
              <li>transcript, voice recording, etc.</li>
              <li>documentation for yourself</li>
              <li>communication</li>
              <li><em>visibility</em></li>
            </ul>
          </li>
          <li>weekly standups</li>
          <li>tools
            <ul>
              <li>github - get client subscribed to commit feed for visibility (they don’t need to understand)</li>
              <li>pivotal tracker
                <ul>
                  <li>client prioritization of stories</li>
                  <li>emergent velocity is crucial</li>
                  <li><em>use low velocity as an argument for fixing tech debt</em></li>
                </ul>
              </li>
              <li>basecamp &amp; campfire for communication</li>
            </ul>
          </li>
        </ul>
      </li>
      <li>fix codebase
        <ul>
          <li>peer programming
            <ul>
              <li>transfer domain knowledge</li>
              <li>teaches best practices</li>
              <li>keeps you focused</li>
            </ul>
          </li>
          <li>integration tests are a necessity on rescue missions
            <ul>
              <li>cover common paths</li>
              <li><em>integration tests for existing behavior, functional/unit tests for added or modified behavior</em></li>
            </ul>
          </li>
          <li>work in small chunks, mixing in:
            <ul>
              <li>client value</li>
              <li>low impact, high yield pieces</li>
              <li>reduce tech debt</li>
            </ul>
          </li>
          <li>focus on issues <em>slowing you down</em></li>
          <li>DON’T GET DISTRACTED by all the issues, just record them and move on
            <ul>
              <li>don’t do code comments, because client can’t see that</li>
            </ul>
          </li>
          <li><em>remote tracking</em> feature branches
            <ul>
              <li>isolate refactoring</li>
              <li>increase visibility</li>
              <li>protects you from rabbit hole excursions - you can always trash the whole thing</li>
              <li>git remote branch gem available</li>
            </ul>
          </li>
          <li>balance of refactorings w/ features</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Other field tactics
    <ul>
      <li>Too many models
        <ul>
          <li>consider a much more denormalized model than often desired</li>
          <li>it’s never just one more model to throw in</li>
          <li><em>extra code is a liability</em></li>
        </ul>
      </li>
    </ul>
  </li>
</ul>
]]></content>
</entry><entry>
  <title>GridFS with Mongoid and CarrierWave on Rails 3</title>
  <link href="http://socialmemorycomplex.net/2010/06/02/gridfs-with-mongoid-and-carrierwave-on-rails-3/" />
  <updated>2010-06-02T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/06/02/gridfs-with-mongoid-and-carrierwave-on-rails-3/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>Over the last week I’ve started a project with <a href="https://guides.rails.info/3_0_release_notes.html">Rails 3</a> and I’m impressed. The increased configurability of the framework has not diminished its ease of use nor its core concepts in the slightest. You’ll have to get used to a few new conventions, especially regarding routing, but there’s lots of help out there.</p>

<p>Since this project is something I’m doing in my off time, I decided to experiment with <a href="https://www.mongodb.org/">MongoDB</a> using the <a href="https://mongoid.org">Mongoid</a> framework. I had played with MongoMapper before, but always felt like I was using an ActiveRecord clone that didn’t take advantage of the full capabilities of a document database and was forcing and ActiveRecord-style approach on me. With Mongoid you get has_many, has_one, and belongs_to relationships that map to MongoDB concepts like embedded documents. Mongoid is fully compatible with the <a href="https://github.com/rails/rails/tree/master/activemodel">ActiveModel</a> interface for Rails3, and things like associations and nested attributes work out of the box.</p>

<p>I also had been hearing great things about <a href="https://github.com/jnicklas/carrierwave">CarrierWave</a> from co-workers. It employs the concept of an “uploader” outside of the MVC ecosystem. The uploader handles resizing, storage, and all other details. In your model, you simply “mount” the uploader and you’re golden. Of course, for this project the killer feature is the GridFS storage option, which is something I wanted to play with.</p>

<p><a href="https://www.mongodb.org/display/DOCS/GridFS+Specification">GridFS</a> is a feature of MongoDB that allows storage of large files inside the database. It chunks the file into pieces and assigns a database index so the file can be associated with other documents. While CarrierWave takes care of getting the file <em>into</em> GridFS, serving the file back out is a bit trickier. CarrierWave gives you all you need to configure the url at which your file will be served, but you have to roll your own mechanism for serving it. But I’ll walk you through it.</p>

<p>I’ll assume you have the right version of Rails 3 installed - it’s changing too frequently to document here. Once you’ve got that, create your app with <code class="language-plaintext highlighter-rouge">rails appname --skip-activerecord</code> and navigate up in that piece.</p>

<p>I’ve discovered through trial and error that your Bundler config for all the gems mentioned here should track their respective master git branches, since a lot of the Rails 3 compatibility issues are still being worked out. I also track Rails edge because, at this point, why wouldn’t you? So, get your Gemfile looking like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>source :rubygems
gem 'bson_ext'

gem 'rails', :git =&gt; 'https://github.com/rails/rails.git', :branch =&gt; 'master'
gem 'mongoid', :git =&gt; 'git://github.com/durran/mongoid.git'
gem 'carrierwave', :git =&gt; "git://github.com/jnicklas/carrierwave.git"
gem 'mini_magick', :git =&gt; 'git://github.com/probablycorey/mini_magick.git'
</code></pre></div></div>

<p>I included <a href="https://github.com/probablycorey/mini_magick">MiniMagick</a>, but you can choose your own image processing library - just remember to change lines referencing MiniMagick in future code examples.</p>

<p>Now let’s install your gem bundle. I recommend calling <code class="language-plaintext highlighter-rouge">bundle install vendor</code> to get all your gems vendored in your Rails app, which makes tracking gems much more straightforward.</p>

<p>Next step is to run <code class="language-plaintext highlighter-rouge">rails generate mongoid:config</code> which generates a <code class="language-plaintext highlighter-rouge">config/mongoid.yml</code> file. You’ll need to fill in the details, but I recommend something a bit like this just to get started:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>defaults: &amp;defaults
  host: localhost

development:
  &lt;&lt;: *defaults
  database: appname_development

test:
  &lt;&lt;: *defaults
  database: appname_test
</code></pre></div></div>

<p>The generator will also place <code class="language-plaintext highlighter-rouge">require 'mongoid/railtie'</code> at the top of your <code class="language-plaintext highlighter-rouge">config/application.rb</code> file. I recommend setting up your generators with Mongoid by adding this line in the config block:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>config.generators do |g|
  g.orm :mongoid
  g.template_engine :erb # this could be :haml or whatever
  g.test_framework :test_unit, :fixture =&gt; false # this could be :rpsec or whatever
end
</code></pre></div></div>

<p>Those generator settings will allow the resource generator to give you exactly the models, views, and controllers you want by invoking <code class="language-plaintext highlighter-rouge">rails generate scaffold thing</code>. Now let’s go into <code class="language-plaintext highlighter-rouge">app/models/thing.rb</code> and add the following:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'carrierwave/orm/mongoid'

class Thing
  include Mongoid::Document
  mount_uploader :image, ImageUploader
end
</code></pre></div></div>

<p>This is the equivalent of Paperclip’s <code class="language-plaintext highlighter-rouge">has_attached_file</code> or Attachment_fu’s <code class="language-plaintext highlighter-rouge">has_attachment</code> - except that you don’t do all the configuration for upload processing there. Instead you do it in the uploader class, which you can generate by invoking <code class="language-plaintext highlighter-rouge">rails generate uploader image</code>. This will create an <code class="language-plaintext highlighter-rouge">uploaders/image.rb</code> file, which is a slight quirk because Rails doesn’t know how to find this file when looking up the <code class="language-plaintext highlighter-rouge">ImageUploader</code> class. We’re going to change the name of the file to <code class="language-plaintext highlighter-rouge">uploaders/image_uploader.rb</code> so it conforms to ruby’s conventions for class definition files.</p>

<p>I’m going to use MiniMagick to process thumbnails, so here’s my fully configured uploader file:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'carrierwave/processing/mini_magick'

class ImageUploader &lt; CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  
  version :thumb do
    process :resize_to_fill =&gt; [80,80]
  end
end
</code></pre></div></div>

<p>There’s some CarrierWave settings we should set up globally, such as all the MongoDB and GridFS stuff. An initializer is the best place for that junk, so stick this in a new file called <code class="language-plaintext highlighter-rouge">config/initializers/carrierwave.rb</code>:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>CarrierWave.configure do |config|
  config.grid_fs_database = Mongoid.database.name
  config.grid_fs_host = Mongoid.config.master.connection.host
  config.storage = :grid_fs
  config.grid_fs_access_url = "/images"
end
</code></pre></div></div>

<p>Note the <code class="language-plaintext highlighter-rouge">config.grid_fs_access_url = "/images"</code> line, which helps CarrierWave figure out what url to serve this under. The actual url it generates will look like <code class="language-plaintext highlighter-rouge">/images/uploads/version_filename.jpg</code>, which is fine for now - you can configure this to your liking later.</p>

<p>Now we just need to update the form to allowing file uploads. Make your “thing” form partial look like this, noting the file field and mulitpart form lines in particular:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;%= form_for(@thing, :html =&gt; { :multipart =&gt; true }) do |f| %&gt;
  &lt;% if @thing.errors.any? %&gt;
    &lt;div id="error_explanation"&gt;
      &lt;h2&gt;&lt;%= pluralize(@thing.errors.count, "error") %&gt; prohibited this thing from being saved:&lt;/h2&gt;

      &lt;ul&gt;
      &lt;% @thing.errors.full_messages.each do |msg| %&gt;
        &lt;li&gt;&lt;%= msg %&gt;&lt;/li&gt;
      &lt;% end %&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  &lt;% end %&gt;
  
  &lt;%= f.label :image %&gt;
  &lt;%= f.file_field :image %&gt;

  &lt;div class="actions"&gt;
    &lt;%= f.submit %&gt;
  &lt;/div&gt;
&lt;% end %&gt;
</code></pre></div></div>

<p>And let’s amend the show view to display the image. Notice we pass the version into the <code class="language-plaintext highlighter-rouge">url</code> method to access a particular version.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;p id="notice"&gt;&lt;%= notice %&gt;&lt;/p&gt;
&lt;%= image_tag @thing.image.url(:thumb) %&gt;

&lt;%= link_to 'Edit', edit_thing_path(@thing) %&gt; |
&lt;%= link_to 'Back', things_path %&gt;
</code></pre></div></div>

<p>We can start up the server by invoking <code class="language-plaintext highlighter-rouge">rails server</code>. Navigating to <code class="language-plaintext highlighter-rouge">https://localhost:3000/things/new</code> should give us a form where we can select an image to upload. The image should get uploaded and the “thing” saved without a hitch, but when it redirects you to view the “thing” there will be a broken image waiting for you. This is because Rails has no freakin’ clue how to access the file via GridFS. So we need to tell it how.</p>

<p>In order to serve the image as quickly as possible, we need a way to access GridFS without involving the entire Rails slow-ass stack. Enter Rails Metal, which allows you to process requests directly from Rack. While Rails 2 required you to place metal processing in its own directory under app, Rails 3 bakes Rack support directly into the inheritance hierarchy of ActionController, allowing you to do something like this:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>require 'mongo'

class GridfsController &lt; ActionController::Metal
  def serve
    gridfs_path = env["PATH_INFO"].gsub("/images/", "")
    begin
      gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r')
      self.response_body = gridfs_file.read
      self.content_type = gridfs_file.content_type
    rescue
      self.status = :file_not_found
      self.content_type = 'text/plain'
      self.response_body = ''
    end
  end
end
</code></pre></div></div>

<p>Save this file as <code class="language-plaintext highlighter-rouge">app/controllers/gridfs_controller</code>. Notice that we’re pulling details about the request path directly out of the request. By default, CarrierWave stores files in GridFS under “uploads/filename”. Therefore, we need to turn the request path (<code class="language-plaintext highlighter-rouge">/images/uploads/filename</code>) into a GridFS file path by simply removing the “/images/” (note both slashes). All of these settings are fully configurable in CarrierWave, but that’s beyond the scope of this article - just don’t forget to modify this controller if you change the url or GridFS storage path.</p>

<p>Now the last part is to set up the route for the image. Open up <code class="language-plaintext highlighter-rouge">config/routes.rb</code> and add a line for our GridfsController:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Example::Application.routes.draw do |map|
  match "/images/uploads/*path" =&gt; "gridfs#serve"
  resources :things
end
</code></pre></div></div>

<p>This maps a url like <code class="language-plaintext highlighter-rouge">/images/uploads/thumb_image.jpg</code> to the GridfsController’s <code class="language-plaintext highlighter-rouge">serve</code> action.</p>

<p>You should now see an thumbnail image on the show view for the “thing”. Congratulations - you’re cooking with GridFS now! There’s a ton of other cool stuff in Rails 3, CarrierWave, and Mongoid, but this should give you the basics for how to handle uploads with GridFS. Have fun, and let me know if I fucked anything up!</p>
]]></content>
</entry><entry>
  <title>Add Sound to Autotest on OS X</title>
  <link href="http://socialmemorycomplex.net/2010/04/14/add-sound-to-autotest/" />
  <updated>2010-04-14T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/04/14/add-sound-to-autotest/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>To me, development is all about communication. With clients and other developers, sure, but mostly with the computer itself. I’m trying to describe to the computer how to accomplish a task it does not have any capacity to understand or appreciate. On the other hand, the context of a given problem can be so natural to me that I have a hard time articulating it. Using <a href="https://github.com/grosser/autotest">autotest</a>, I can engage in a sort of conversation with the computer, where it tells me in real time as I program whether it understands what I’m telling it or not.</p>

<p>A Growl notification informing me of test results is great, and I can even tell Growl to play a sound when the notification is ready. But that sound tells me to look for the notification, not whether the tests pass or fail. To make this conversation more fluid, it would be nice if I had not just visual but also audio feedback which told me immediately what the test results were, instead of having to constantly context switch to the test results.</p>

<p>There have been a <a href="https://www.fozworks.com/2007/7/28/autotest-sound-effects">few</a> <a href="https://www.metaskills.net/2008/4/6/autotest-playlist-for-red-green-feedback">attempts</a> to do this already, but they all seem so complex. I found a simple command line sound file player called <a href="https://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/afplay.1.html">afplay</a> that makes all this trivial. In your ~/.autotest file, add the following:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>def play(filename, volume = ".15")
  system "afplay -v #{volume} /Users/jeremyweiland/.autotest_sounds/#{filename}.wav"
end
 
Autotest.add_hook :ran_command do |at|
  play(at.results.detect { |line| line.include?("0 failures, 0 errors") } ? "passed" : "failed")
end

Autotest.add_hook :run_command do |at|
  play("running")
end
</code></pre></div></div>

<p>This will play some select sounds when tests start running, pass, and fail. Just drop audio files in ~/.autotest_sounds and name them appropriately. Here are <a href="/media/dot-autotest_sounds.zip">my sounds</a> to get you started. The “play” method can be modified to use the “say” command or play any sound file you want.</p>

<p>I find that being able to use my ears to help have this difficult conversation helps me stay in the flow of the conversation more, where I do better and faster work.</p>
]]></content>
</entry><entry>
  <title>Full Disclosure</title>
  <link href="http://socialmemorycomplex.net/2010/03/14/full-disclosure/" />
  <updated>2010-03-14T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2010/03/14/full-disclosure/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>You can inspect the software that generates this blog on <a href="https://github.com/jeremy6d/jekyll">Github</a>. I borrowed heavily from <a href="https://github.com/henrik/jekyll">one developer</a> to integrate Haml with pagination into <a href="https://github.com/mojombo/jekyll">Jekyll</a>. It took a while (like all night) but it works. Tests are failing all over the place, though, so fork with caution.</p>
]]></content>
</entry><entry>
  <title>leftlibertarian.org Beta Relaunch</title>
  <link href="http://socialmemorycomplex.net/leftlibertarian/2009/12/30/leftlibertarian-org-beta-relaunch/" />
  <updated>2009-12-30T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/leftlibertarian/2009/12/30/leftlibertarian-org-beta-relaunch/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p><a href="https://leftlibertarian.org">leftlibertarian.org</a> is back! I’ve moved the site off WordPress, which was giving me too many problems. The site should be simple enough - there’s no commenting, and the core functionality has nothing to do with <em>creating</em> content, only publishing it. So I started thinking about why I was going out and gathering / parsing feeds when Google Reader does it perfectly well, and has an API I can access.</p>

<p>The new site has a Google Reader account associated with it (leftlibertarian.org). Instead of going out to a list of feeds, downloading them, databasing posts, and generating web pages on requests, I just grab a JSON encoded version of my reading list as if my site were a Google Reader user and generate pages off of that! Super fast, super lightweight, super easy (once I figured out how I wanted to go about it).</p>

<p>The cool thing about this is that the API makes available just about all of the Google Reader features, including starring, comments, sharing, etc. The Google Reader web application is really just a front end for a rather powerful backend. Over the long run, I’d like to leverage these features to make the site more socially driven and dynamic but without needing a database or anything but a basic web server, cron, and ruby.</p>

<p>The site is very much beta right now. I’m using a HTML parsing library to truncate posts, so if you see anomalies there or have any other comments, let me know. admin atsign left libertarian period org</p>
]]></content>
</entry><entry>
  <title>acts_as_enumerated Blowing Up Your Testing Spot?</title>
  <link href="http://socialmemorycomplex.net/2009/12/24/acts-as-enumerated/" />
  <updated>2009-12-24T00:00:00+00:00</updated>
  <id>http://socialmemorycomplex.net/2009/12/24/acts-as-enumerated/</id>
  <author><name>Jeremy Weiland</name></author>
  <content type="html"><![CDATA[<p>If acts_as_enumerated classes are borking when you run your tests, here’s a nasty workaround I did that just might work for you:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>class MembershipStatus &lt; ActiveRecord::Base
  if RAILS_ENV == 'test'
    def self.[](label)
      case label
      when :pending
        MembershipStatus.new(:id =&gt; 1)
      when :accepted
        MembershipStatus.new(:id =&gt; 2)
      when :denied
        MembershipStatus.new(:id =&gt; 3)
      when :invited
        MembershipStatus.new(:id =&gt; 4)
      end
    end
  else
    acts_as_enumerated
  end
end
</code></pre></div></div>
]]></content>
</entry>
</feed>
