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

<channel>
	<title>corprewland &#187; rails</title>
	<atom:link href="http://www.corprew.org/blog/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.corprew.org</link>
	<description>(dis)information organization</description>
	<lastBuildDate>Thu, 04 Feb 2010 20:48:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Authlogic and the iPhone</title>
		<link>http://www.corprew.org/blog/2010/01/27/authlogic-and-objectiveresource/</link>
		<comments>http://www.corprew.org/blog/2010/01/27/authlogic-and-objectiveresource/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 00:45:45 +0000</pubDate>
		<dc:creator>corprew</dc:creator>
				<category><![CDATA[computer programming]]></category>
		<category><![CDATA[authlogic]]></category>
		<category><![CDATA[defensive programming]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[ObjectiveResource]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[UserSession]]></category>

		<guid isPermaLink="false">http://www.corprew.org/?p=235</guid>
		<description><![CDATA[So, I&#8217;ve based a couple of apps on a combination of authlogic and the iPhone Objective Resource package, and when I mentioned this on the relevant lists I got a bunch of people asking me questions, so I thought I&#8217;d post about what I did generally. There are a couple of steps, most of which [...]]]></description>
			<content:encoded><![CDATA[<p>So, I&#8217;ve based a couple of apps on a combination of <a href="http://github.com/binarylogic/authlogic">authlogic</a> and the iPhone <a href="http://iphoneonrails.com/">Objective Resource</a> package, and when I mentioned this on the relevant lists I got a bunch of people asking me questions, so I thought I&#8217;d post about what I did generally.</p>
<p>There are a couple of steps, most of which are geared towards having authlogic not produce redirects and instead produce http status codes that are interpretable to the applications.  Here&#8217;s an example of what I mean from my ApplicationController on an app</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> require_user
    <span style="color:#9966CC; font-weight:bold;">unless</span> current_user
      store_location
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;You must be logged in to access this page&quot;</span>
      respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#006600; font-weight:bold;">&#123;</span> redirect_to new_user_session_url <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;you must be logged in to access this page.&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:unauthorized</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>In the default implementation of this filter, it always returns a redirect.  ObjectiveResource can follow the redirect (if you have a recent enough version), but it doesn&#8217;t really do it a lot of good.  This way, you get a status code that you can use.</p>
<p>Since Authlogic focuses on RESTful creation of things, a lot of operations map naturally.  To create an account on the Rails app, create a User object, and to test whether the user can log in, create a user session.  My application stores credentials between iPhone App invocations, so it creates a UserSession at startup if you have stored credentials.</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #002200;">-</span> <span style="color: #002200;">&#40;</span><span style="color: #a61390;">void</span><span style="color: #002200;">&#41;</span>applicationDidFinishLaunching<span style="color: #002200;">:</span><span style="color: #002200;">&#40;</span>UIApplication <span style="color: #002200;">*</span><span style="color: #002200;">&#41;</span>application <span style="color: #002200;">&#123;</span>
<span style="color: #11740a; font-style: italic;">//</span>
<span style="color: #11740a; font-style: italic;">// ... blah blah blah all sorts of stuff removed.</span>
<span style="color: #11740a; font-style: italic;">//</span>
&nbsp;
	UserPrefsManager<span style="color: #002200;">*</span> prefs <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>UserPrefsManager sharedInstance<span style="color: #002200;">&#93;</span>;
&nbsp;
	<span style="color: #a61390;">if</span> <span style="color: #002200;">&#40;</span><span style="color: #002200;">&#91;</span>prefs isLoggedIn<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
		UserSession <span style="color: #002200;">*</span> us <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>UserSession alloc<span style="color: #002200;">&#93;</span> init<span style="color: #002200;">&#93;</span> autorelease<span style="color: #002200;">&#93;</span>;
&nbsp;
		us.login <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>prefs username<span style="color: #002200;">&#93;</span>;
		us.password <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span>prefs password<span style="color: #002200;">&#93;</span>;
&nbsp;
		<span style="color: #400080;">NSError</span> <span style="color: #002200;">*</span> err <span style="color: #002200;">=</span> <span style="color: #a61390;">nil</span>;
&nbsp;
		<span style="color: #a61390;">if</span><span style="color: #002200;">&#40;</span><span style="color: #002200;">!</span><span style="color: #002200;">&#91;</span>us createRemoteWithResponse<span style="color: #002200;">:&amp;</span>err<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#41;</span>
		<span style="color: #002200;">&#123;</span>
<span style="color: #11740a; font-style: italic;">//</span>
<span style="color: #11740a; font-style: italic;">//  ... my actual detection stuff removed and just the default left ...</span>
<span style="color: #11740a; font-style: italic;">//</span>
			<span style="color: #002200;">&#91;</span>AlertHelper showAlertWithError<span style="color: #002200;">:</span>err<span style="color: #002200;">&#93;</span>;
			<span style="color: #002200;">&#91;</span>prefs clearLogin<span style="color: #002200;">&#93;</span>;
		<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#125;</span>
	<span style="color: #002200;">&#91;</span>ObjectiveResourceConfig setUser<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>prefs username<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
	<span style="color: #002200;">&#91;</span>ObjectiveResourceConfig setPassword<span style="color: #002200;">:</span><span style="color: #002200;">&#91;</span>prefs password<span style="color: #002200;">&#93;</span><span style="color: #002200;">&#93;</span>;
<span style="color: #11740a; font-style: italic;">//</span>
<span style="color: #11740a; font-style: italic;">// ... and proceed on with your app's normal course of things ...</span>
<span style="color: #11740a; font-style: italic;">//	</span>
    <span style="color: #002200;">&#91;</span>window addSubview<span style="color: #002200;">:</span>tabBarController.view<span style="color: #002200;">&#93;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>You see here that i&#8217;m creating an UserSession here and testing to see if it works and setting the ObjectiveResourceConfig properties if it does.  I have some logic where if there isn&#8217;t saved credentials you will get a dialog asking you to login or create an account (or whatever) later on, which is the point of <code>[prefs clearLogin];</code>.  This is matched by a change to the create method of the UserSessionController:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">      respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">format</span> <span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Login successful!&quot;</span>
          redirect_back_or_default account_url
        <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span> <span style="color:#9966CC; font-weight:bold;">do</span>
          render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@user_session</span>, <span style="color:#ff3333; font-weight:bold;">:status</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>(For brevity, I&#8217;ve just shown the successful branch)</p>
<p>This should be enough to get people going &#8212; all the other changes you have to make can be figured out from these two statements, and when I have some spare time I&#8217;m going to create a version of the demo application that works with ObjectiveResource.  The only other suggestion I have is to use the withResponse: versions of everything and code defensively, and note that in some versions of ObjectiveResource getting an error from your application will cause the application to throw.  In the meantime, feel free to ask me any questions</p>
]]></content:encoded>
			<wfw:commentRss>http://www.corprew.org/blog/2010/01/27/authlogic-and-objectiveresource/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>federated search party (tl; dr)</title>
		<link>http://www.corprew.org/blog/2009/07/23/federated-search-party-tl-dr/</link>
		<comments>http://www.corprew.org/blog/2009/07/23/federated-search-party-tl-dr/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 20:39:05 +0000</pubDate>
		<dc:creator>corprew</dc:creator>
				<category><![CDATA[computer programming]]></category>
		<category><![CDATA[infosci]]></category>
		<category><![CDATA[aboutLastNight]]></category>
		<category><![CDATA[celiaq]]></category>
		<category><![CDATA[content serach]]></category>
		<category><![CDATA[federated search]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[relevance]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tagging]]></category>
		<category><![CDATA[tfidf]]></category>
		<category><![CDATA[yourmomusesinformationscienceconcepts]]></category>

		<guid isPermaLink="false">http://www.corprew.org/?p=217</guid>
		<description><![CDATA[I&#8217;m making this post to elucidate some conversations I had late night last night, none of this is particularly rocket science or necessarily even model rocket science. One hilarious thing that keeps coming up is federating search &#8212; combining search results from multiple datastores, which is a moderately hard problem to come up with a [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m making this post to elucidate some conversations I had late night last night, none of this is particularly rocket science or necessarily even model rocket science.  One hilarious thing that keeps coming up is federating search &#8212; combining search results from multiple datastores, which is a moderately hard problem to come up with a general solution for, but relatively easy (frequently) to come up with a solution for a particular purpose.</p>
<p>Complicated general solutions (such as that found in <a href="http://jcp.org/en/jsr/detail?id=170>JSR 170 and similar systems</a>), involve figuring out the relationships between properties and their search indices.  For example, all documents in a content management system have a title, right?  Well, some might have a title but have it indexed in lower case and others might have a name property indexed in the case it was entered into the system in and so on.</p>
<p>celiaq, for example, has three different search stores that it uses, a &#8216;normal&#8217; database (mysql), a full text database (also using mysql), and it also searches amazon&#8217;s catalog.  (It also searches <a href="http://geonames.org/">GeoNames</a> for a lot of content information, but it doesn&#8217;t federate that with other results and uses a couple of other data sources that aren&#8217;t relevant to this.)</p>
<p>Here&#8217;s the (relatively trivial) code that does &#8216;content&#8217; (normally: fulltext but in content management systems called &#8216;content search&#8217;) searching.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Contentsearch
  <span style="color:#9966CC; font-weight:bold;">module</span> ClassMethods; <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">included</span><span style="color:#006600; font-weight:bold;">&#40;</span>klass<span style="color:#006600; font-weight:bold;">&#41;</span>
    klass.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span>ClassMethods<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> ft_index
    logger.<span style="color:#9900CC;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;[contentsearch::ftindex] submitting #{self.id} #{self.name}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Bj.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">&quot;./script/runner jobs/add_to_consearch.rb -t #{self.class.name.downcase} -i #{self.id}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> ft_deindex
    logger.<span style="color:#9900CC;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;[contentsearch::ftdeindex] removing #{self.id} #{self.name}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Bj.<span style="color:#9900CC;">submit</span> <span style="color:#996600;">&quot;./script/runner jobs/remove_from_consearch.rb -t #{self.class.name.downcase} -i #{self.id}&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">module</span> ClassMethods
    <span style="color:#9966CC; font-weight:bold;">def</span> ft_search<span style="color:#006600; font-weight:bold;">&#40;</span>kw_string<span style="color:#006600; font-weight:bold;">&#41;</span>
      clsname = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">name</span>.<span style="color:#9900CC;">downcase</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;s&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_by_sql</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;select distinct #{clsname}.id, lots of stuff i deleted here, MATCH(content) against (?) as relevance FROM #{clsname},consearches WHERE consearches.ftable_id = #{clsname}.id and consearches.ftable_type='#{self.name}' and match(content) against (?) order by relevance limit 6&quot;</span>,kw_string,kw_string<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This example is written in Ruby (on Rails), and the first part is just a convention for putting class methods into a ruby class.  How Ruby (and smalltalk and similar languages) handle methods is a fascinating but different discussion but essentially it&#8217;s a <a href="http://en.wikipedia.org/wiki/Metaprogramming">metaprogramming</a> party and everyone&#8217;s invited.</p>
<p>Ruby makes this relatively simple to add as a module to pretty much any class.  The reason that ft_index and ft_deindex run in a background process is because taking a document in or out of a fulltext indexed mysql database is way slower than you would want to present to the user in an interactive process.  This is common in web applications and is part of why you see things like &#8220;your [whatever] may not appear in searches right away&#8221; from a lot of applications.  If you leave them to run on their own they&#8217;re fast enough but generally would make the user unhappy.</p>
<p>But basically, what&#8217;s going on here is that there&#8217;s two separate tables (and different table types in mysql &#8212; one of which does fulltext searching and the other of which has ACID properties.)  By joining these two tables together, you can search against the content tables and get results back from the main table that stores domain objects.  This is probably the simplest version of federating two different search types together.  It works pretty smoothly and this sort of thing is in a number of different products.  </p>
<p>(And for rails people, the relevant string in the model classes for this is <code>has_one :consearch, :as => :ftable</code>)</p>
<p>But this is obviously trivially simple:  the objects in the content search table are <em>representations</em> of the objects in the main table, and there are entirely <em>separate</em> semantics between the two tables (and unfortunately i deleted the examples using both the main and consearch table, but it&#8217;s a join and you get the idea.)  One of the tables does &#8216;field operator value&#8217; type searching (ie: relational) and the other is the kind referred to these days as &#8216;google searching.&#8217;</p>
<p>Things get progressively more difficult when one of these things aren&#8217;t true &#8212; that there isn&#8217;t a store that has the single unified version of the document or that the semantics are related but not either identical or entirely different.  For example, if I&#8217;m searching two different instantiations of my own product, it&#8217;s fairly easy &#8212; all the fields mean the same thing between the two different databases.</p>
<p>If the products differ by schema or meaning of the schema, you have to make a (semantic) translation between the two to make the search work, and also you have to make some sort of translation on the search results to have the results displayed to the user in a way that makes sense.  This might be as simple as &#8216;one repository has names and one things have titles&#8217; or it might be more complex (names versus ids, names in particular formats, URLs versus descriptive strings, date formats that give seconds versus those that are accurate to the day, etc&#8230;)</p>
<p>It&#8217;s when you start combining these sorts of things that stuff starts getting more complex.  (This is also leaving aside the issue that the <em>protocols</em> to access all of this information is different (although these days more and more of this becomes an adventure in XML parsing and not DLL hell.)  Let&#8217;s take a simple example, sorting.</p>
<p>Say I have three different datastores Repo1 &#8211; Repo3, and they both return objects with titles on them, and I&#8217;m sorting the titles:</p>
<p>Repo1: [Alpha, Bravo, Charlie, Delta, Echo, Foxtrot ]<br />
Repo2: [Able, Baker, Charlie, Dog, Easy, Fox]<br />
Repo3: [Alligator, Crocodile, Pterosaur]</p>
<p>It&#8217;s fairly easy to implement this sort, there are a few small issues (like paging results versus the page sizes of the underlying repositories, but regardless alphabetic sorts are well-understood in most locales.</p>
<p>However, if you&#8217;re searching by something more like &#8216;<a href="http://en.wikipedia.org/wiki/Relevance_%28information_retrieval%29">relevance</a>&#8216;, you get back a  number associated with each result (so the document that had the &#8216;Alpha&#8217; before might have a score of &#8217;0.91&#8242;).  It&#8217;s simple to order numbers as well, but how do you tell that a number in one datastore corresponds to a number in another?  For one thing, those numbers are calculated (mostly) with regards to the particular collection of documents on a given datastore and for another, one repository may just tend to return a higher number for documents that are theoretically as relevant (because there isn&#8217;t any agreement about what 0.91 means, it&#8217;s just what a function returns.)</p>
<p>So those two things are where it starts to get more complex and needing actual customization and specialization. </p>
<p>In conclusion, this is way too (f) long for the blog, but I was typing it up to explain things that I was talking about yesterday anyway.  HTH.  Feel free to comment, but if you&#8217;re the person I&#8217;m proximately writing this for, you should probably send email.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.corprew.org/blog/2009/07/23/federated-search-party-tl-dr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I am up to at the moment</title>
		<link>http://www.corprew.org/blog/2009/03/08/what-i-am-up-to-at-the-moment/</link>
		<comments>http://www.corprew.org/blog/2009/03/08/what-i-am-up-to-at-the-moment/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 19:12:40 +0000</pubDate>
		<dc:creator>corprew</dc:creator>
				<category><![CDATA[computer programming]]></category>
		<category><![CDATA[location-based]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[geolocation]]></category>
		<category><![CDATA[geolocations]]></category>
		<category><![CDATA[hacketyhackhack]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.corprew.org/?p=191</guid>
		<description><![CDATA[This is more or less a good guide to what I am up to at the moment, although it should be noted that I&#8217;ve written this same code fragment in three languages in the last while (this is ruby, the others were PHP and Java, although the Java one was a festival of reflection due [...]]]></description>
			<content:encoded><![CDATA[<p>This is more or less a good guide to what I am up to at the moment, although it should be noted that I&#8217;ve written this same code fragment in three languages in the last while (this is ruby, the others were PHP and Java, although the Java one was a festival of reflection due to type wackiness.)</p>
<p>I actually have another version of the same code that puts a URL in the debug log that can be used to click directly to google maps.  Why?  I don&#8217;t know.  I&#8217;m beginning to value Aptana Studio&#8217;s remix of Eclipse more and more as time goes on though because I now have Java, PHP, and Ruby/Rails all in the same highly (mostly) performing IDE.  The alleged iPhone mode doesn&#8217;t work on my computer but I have CRAZY LIBERRIES installed at the moment and I suspect that that&#8217;s in large part my own fault &#8212; the apple tools still work.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> geo_desc <span style="color:#006600; font-weight:bold;">&#40;</span> geo_loc, extended = <span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
     <span style="color:#008000; font-style:italic;">#</span>
     <span style="color:#008000; font-style:italic;">#  specialized pretty printer for address types.</span>
     <span style="color:#008000; font-style:italic;">#  note that there is pretty much a standard mixin for geo stuff and</span>
     <span style="color:#008000; font-style:italic;">#  this works across all the geocoding packages and model types.</span>
     <span style="color:#008000; font-style:italic;">#</span>
     <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">&quot;[nil location]&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> geo_loc.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc = <span style="color:#996600;">&quot;[&quot;</span> 
     desc <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">&lt;</span> geo_loc.<span style="color:#9900CC;">country_code</span>.<span style="color:#9900CC;">downcase</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">country_code</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;.&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> geo_loc.<span style="color:#9900CC;">state</span>.<span style="color:#9900CC;">downcase</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">state</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;.&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> geo_loc.<span style="color:#9900CC;">city</span>.<span style="color:#9900CC;">downcase</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">city</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;.&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> geo_loc.<span style="color:#9900CC;">zip</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">zip</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;] &quot;</span>
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;[&quot;</span>
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> geo_loc.<span style="color:#9900CC;">lat</span>.<span style="color:#9900CC;">to_s</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">lat</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;,&quot;</span>
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> geo_loc.<span style="color:#9900CC;">lng</span>.<span style="color:#9900CC;">to_s</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">lng</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">precision</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#9966CC; font-weight:bold;">or</span> geo_loc.<span style="color:#9900CC;">precision</span> == <span style="color:#996600;">&quot;unknown&quot;</span>
       desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot; (&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> geo_loc.<span style="color:#9900CC;">precision</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;)&quot;</span> 
     <span style="color:#9966CC; font-weight:bold;">else</span>
       desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot; ?&quot;</span>
     <span style="color:#9966CC; font-weight:bold;">end</span>
     desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;]&quot;</span>
     <span style="color:#9966CC; font-weight:bold;">if</span> extended
       desc <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot; &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> geo_loc.<span style="color:#9900CC;">full_address</span> <span style="color:#9966CC; font-weight:bold;">unless</span> geo_loc.<span style="color:#9900CC;">full_address</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
     <span style="color:#9966CC; font-weight:bold;">end</span>
     <span style="color:#0000FF; font-weight:bold;">return</span> desc
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.corprew.org/blog/2009/03/08/what-i-am-up-to-at-the-moment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby/rails and the invited beta</title>
		<link>http://www.corprew.org/blog/2008/04/16/rubyrails-and-the-invited-beta/</link>
		<comments>http://www.corprew.org/blog/2008/04/16/rubyrails-and-the-invited-beta/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 06:31:59 +0000</pubDate>
		<dc:creator>corprew</dc:creator>
				<category><![CDATA[computer programming]]></category>
		<category><![CDATA[account]]></category>
		<category><![CDATA[acts_as_authenticated]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[guid]]></category>
		<category><![CDATA[invite]]></category>
		<category><![CDATA[invite functionality]]></category>
		<category><![CDATA[private beta]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[slicehost]]></category>
		<category><![CDATA[tristero]]></category>
		<category><![CDATA[welcome screen]]></category>

		<guid isPermaLink="false">http://www.corprew.org/blog/2008/04/16/rubyrails-and-the-invited-beta/</guid>
		<description><![CDATA[I&#8217;ve been working on a website in RoR for the last while, and it&#8217;s about to go live in the private beta sort of way that seems to be so popular these days. It&#8217;s handy that way, because that way I can set up the site at slicehost or similar and not have to worry [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working on a website in RoR for the last while, and it&#8217;s about to go live in the private beta sort of way that seems to be so popular these days.  It&#8217;s handy that way, because that way I can set up the site at slicehost or similar and not have to worry (too much) about my server slowing from getting overloaded.  This same site&#8217;s next incarnation is going to be facebook related, so that should overwhelm any sense of moderation (if I&#8217;m lucky.)</p>
<p>So, the key method of invitation to a private beta is that you mail someone a code allowing them access to the system, for these purposes, let&#8217;s just assume that the code is some reasonably long unique string (in my code, it&#8217;s actually a <code>uuid</code>.)  So, set up a migration something like this to manage them:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    create_table <span style="color:#ff3333; font-weight:bold;">:invites</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
<span style="color:#008000; font-style:italic;"># deleted stuff</span>
      t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:guid</span>
      t.<span style="color:#CC0066; font-weight:bold;">integer</span> <span style="color:#ff3333; font-weight:bold;">:used_yet</span>
<span style="color:#008000; font-style:italic;"># deleted stuff</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><code>used_yet</code> isn&#8217;t a boolean for reasons that are too laborious to go into here, but reflect some functionality in the code that I&#8217;m not going to display.  Assuming that you&#8217;re using acts_as_authentication and are redirecting anyone who tries to access your app to the default welcome page according to the usual methods, set up something like this in your routes.rb:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;welcome&quot;</span></pre></div></div>

<p>This is probably the case in like half the rails apps out there.  Have the <code>index</code> method of the welcome controller put up a form with a field like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#let's see if the formatter can handle rails erb without exploding.</span>
<span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> form_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'welcome/checkinvite'</span>, <span style="color:#ff3333; font-weight:bold;">:method</span><span style="color:#006600; font-weight:bold;">=&gt;</span>:get<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= text_field_tag <span style="color:#996600;">'invite'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span>= submit_tag <span style="color:#996600;">'begin'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">-%&gt;</span></pre></div></div>

<p>This lets the user enter their invite in more or less the normal method.  Now in your &#8216;welcome&#8217; controller, you&#8217;ll need a &#8216;checkinvite&#8217; method that looks something like the following:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"> <span style="color:#9966CC; font-weight:bold;">def</span> checkinvite
    <span style="color:#0066ff; font-weight:bold;">@inviteguid</span> = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:invite</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@invite</span> = Invite.<span style="color:#9900CC;">find_by_guid</span><span style="color:#006600; font-weight:bold;">&#40;</span>@inviteguid<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span>@invite == <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Your invite was invalid&quot;</span>
      redirect_to root_url
      <span style="color:#0000FF; font-weight:bold;">return</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span>@invite.<span style="color:#9900CC;">used_yet</span> == <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;Your invite had already been used&quot;</span>
      redirect_to root_url
      <span style="color:#0000FF; font-weight:bold;">return</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>After this, you&#8217;ll need to have some code in your HTML page that links you to the account/signup functionality of acts_as_authenticated.  I&#8217;m not going to include that because I&#8217;m too lazy to fish it out of my app functionality, but you can do that pretty much with a link_to using <code>:invite=%gt;@invite_guid</code> as an extra parameter.</p>
<p>You need to put the same invite detection code in account/signup, and then when you&#8217;ve created the account, set <code>invite.used_yet = 1</code>.  This is about as simple as a method that I can think of for doing the private beta functionality that seems to be so much in vogue these days.  Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.corprew.org/blog/2008/04/16/rubyrails-and-the-invited-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
