<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>ducktyped - Home</title>
  <id>tag:ducktyped.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://ducktyped.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://ducktyped.com/" rel="alternate" type="text/html"/>
  <updated>2008-08-01T02:04:57Z</updated>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2008-08-01:44</id>
    <published>2008-08-01T01:43:00Z</published>
    <updated>2008-08-01T02:04:57Z</updated>
    <category term="ramaze"/>
    <link href="http://ducktyped.com/2008/8/1/a-minimal-cms-module-for-ramaze-apps" rel="alternate" type="text/html"/>
    <title>A minimal CMS module for Ramaze apps...</title>
<summary type="html">&lt;h2&gt;...and a valuable programming lesson&lt;/h2&gt;

&lt;h3&gt;Preface&lt;/h3&gt;

&lt;p&gt;This post got longer than anticipated, because I refactored my code in the middle of writing this very post. The refactored code is at the bottom. Explanations are carelessly strewn about.&lt;/p&gt;

&lt;h3&gt;Main&lt;/h3&gt;

&lt;p&gt;I was going to write a post about how great Ramaze is and about how I have some ideas for coding conventions that could help with code reuse, sharing, and multi-app capabilities without requiring any new framework-specific code.&lt;/p&gt;

&lt;p&gt;But not now - I need to write shorter posts to get some writing out the door at all. Therefore, I'm just posting some code that implements a simple (primitive?) content management system to keep any site copy in markdown (or textile) format.&lt;/p&gt;</summary><content type="html">
            &lt;h2&gt;...and a valuable programming lesson&lt;/h2&gt;

&lt;h3&gt;Preface&lt;/h3&gt;

&lt;p&gt;This post got longer than anticipated, because I refactored my code in the middle of writing this very post. The refactored code is at the bottom. Explanations are carelessly strewn about.&lt;/p&gt;

&lt;h3&gt;Main&lt;/h3&gt;

&lt;p&gt;I was going to write a post about how great Ramaze is and about how I have some ideas for coding conventions that could help with code reuse, sharing, and multi-app capabilities without requiring any new framework-specific code.&lt;/p&gt;

&lt;p&gt;But not now - I need to write shorter posts to get some writing out the door at all. Therefore, I'm just posting some code that implements a simple (primitive?) content management system to keep any site copy in markdown (or textile) format.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
module StaticPages
  class MainController &amp;lt; Ramaze::Controller

    def self.actions(*args)
      args.each do |meth|
        define_method(meth.to_sym) { render_template(&quot;#{meth}.txt&quot;) }
      end
      cache *args
    end

    map &quot;/content&quot;
    view_root &quot;view/content&quot;
    engine :Maruku
    helper :cache, :aspect
    actions :home, :help, :tos, :footer_snippet

    # Optional expiry methods for convenience
    def expire(page, pass = nil)
      if pass == &quot;secret&quot;
        path = &quot;/content/#{page}&quot;
        action_cache.delete path
        redirect path
      end
    end

    # In dev mode put this in layout:
    # A('Expire all caches', :href =&gt; &quot;/content/expire_all/secret&quot;)
    def expire_all(pass = nil)
      if pass == &quot;secret&quot;
        action_cache.clear
        redirect &quot;/&quot;
      end
    end

  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Explanation&lt;/h3&gt;

&lt;p&gt;What you need with this is a &lt;code&gt;view/content&lt;/code&gt; folder that contains the following files (for this example): &lt;code&gt;home.txt, help.txt, tos.txt, footer_snippet.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, when you write any markdown formatted text in those files it will be automatically rendered as html and action-cached. If you want to include these pages, just call &lt;code&gt;render_partial(&quot;/content/home&quot;)&lt;/code&gt; in any template.&lt;/p&gt;

&lt;p&gt;You can also expire the cached pages (see self-explanatory methods above). In dev mode you can just add a link in your footer to expire all caches and updating content becomes much less painless. No more hand-coding html for static pages in 2008!&lt;/p&gt;

&lt;h3&gt;Caveats&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The maruku (markdown) template engine hooks don't seem to be included with Ramaze 2008.06. You can get the source (just one file) from the &lt;a href=&quot;http://github.com/manveru/ramaze/tree/master/lib/ramaze/template/maruku.rb&quot;&gt;ramaze repo&lt;/a&gt; (direct link) and require it in your app.&lt;/li&gt;
&lt;li&gt;If you want Textile, simply change &lt;code&gt;engine :Maruku&lt;/code&gt; to &lt;code&gt;engine :RedCloth&lt;/code&gt; (note the capitalization).&lt;/li&gt;
&lt;li&gt;You can't have any pages called &quot;expire&quot; or &quot;expire_all&quot;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Critical problem leading to redesign&lt;/h3&gt;

&lt;p&gt;While updating existing pages works in production via the expire actions, this system still requires a restart for newly created pages to show up, as you have to add them manually to the &lt;code&gt;actions :page_name&lt;/code&gt; method. How to get around this?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse the view/content directory for new files and add matching new methods on the fly.&lt;/li&gt;
&lt;li&gt;Do some method_missing tricks, hacking around the dispatcher, etc. (shudder)&lt;/li&gt;
&lt;li&gt;Do the simplest thing that works: use a parameterized action as a catch-all:&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code&gt;
module StaticPages
  class MainController &amp;lt; Ramaze::Controller    
    map &quot;/content&quot;
    view_root &quot;view/content&quot;
    engine :Maruku
    helper :cache, :aspect
    cache :show, :key =&gt; lambda{ request['page'] }

    def show(page = nil)
      page ? render_template(&quot;#{page}.txt&quot;) : redirect(&quot;/&quot;)
    end

    # Optional expiry methods for convenience
    def expire(page, pass = nil)
      if pass == &quot;secret&quot;
        path = Rs(:show, page)
        action_cache.delete path
        redirect path
      end
    end

    # In dev mode put this in layout:
    # A('Expire all caches', :href =&gt; &quot;/content/expire_all/secret&quot;)
    def expire_all(pass = nil)
      if pass == &quot;secret&quot;
        action_cache.clear
        redirect &quot;/&quot;
      end
    end

  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Improved design&lt;/h3&gt;

&lt;p&gt;The redesigned code has an almost identical interface to the original version (the path changed from /content/{page} to /content/show/{page}), but allows adding pages without restarting the server (or source reload). It's also slightly shorter, and clearer. You can now also name your pages expire or expire_all.&lt;/p&gt;

&lt;p&gt;Finally, I'm reminded of one of my favorite programming aphorisms: &quot;All problems can be solved by adding another layer of abstraction, except the problem of having too many layers of abstraction.&quot; &lt;/p&gt;

&lt;p&gt;Call me unsophisticated, but I prefer simple solutions like this mini CMS. It's just a Ruby module containing a Ramaze controller that you simply copy to your project and call via &lt;code&gt;require 'static_pages'&lt;/code&gt; in start.rb. No plugin architecture needed, you know your code, you know where it lives, and you can easily take it with you to another project. That's why I prefer Ramaze over Rails (or even Merb. Sinatra is simple too, but doesn't scale up to large projects, code-structure wise).&lt;/p&gt;

&lt;h3&gt;Calls to action&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;How would you improve my code?&lt;/li&gt;
&lt;li&gt;It would be nice to start a repository of modules/slices of functionality for Ramaze apps to create an ecosystem/platform for code reuse (similar to rails/merb's plugins, but without the (unnecessary) plugin framework.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;License&lt;/h3&gt;

&lt;p&gt;The source code in this article is released under an MIT license, copyright by ben@ the domain of this site. If you use this code, please consider telling me, as it would make me happy and motivate me.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2008-01-04:8</id>
    <published>2008-01-04T00:11:00Z</published>
    <updated>2008-01-04T00:48:12Z</updated>
    <category term="ruby web frameworks"/>
    <link href="http://ducktyped.com/2008/1/4/the-great-ruby-web-framework-multi-app-challenge" rel="alternate" type="text/html"/>
    <title>The great Ruby web framework multi-app challenge</title>
<summary type="html">&lt;p&gt;Many websites are composed of several fairly independent apps that would still benefit from tighter integration than running them as separate apps. Here's a typical site: core site, forum, blog/cms (or photo management app, etc).&lt;/p&gt;

&lt;p&gt;The typical Rails response to multi-app integration is one of the following two: 1. &quot;Just run them as separate apps on different subdomains and share the database.&quot; or 2. &quot;Use the app as the base and add your own code to it.&quot; I have integrated several Rails apps, and it is dirty and inefficient, a real pain in the ass, especially compared to the joy of doing most other things with Ruby/Rails. The failure of multi-app Rails is documented by the plethora of hacks used to emulate multi-app behaviors: generators, engines, appable plugins, and the multi-app routing plugin.&lt;/p&gt;

&lt;p&gt;The point of this post is not to rip on rails, it's just what I'm primarily using, and I would love to see other Ruby web frameworks such as merb, ramaze, and the micro-frameworks think about multi-app while they can still make major changes. Ruby is powerful enough to elegantly enable multi-app configurations.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;Many websites are composed of several fairly independent apps that would still benefit from tighter integration than running them as separate apps. Here's a typical site: core site, forum, blog/cms (or photo management app, etc).&lt;/p&gt;

&lt;p&gt;The typical Rails response to multi-app integration is one of the following two: 1. &quot;Just run them as separate apps on different subdomains and share the database.&quot; or 2. &quot;Use the app as the base and add your own code to it.&quot; I have integrated several Rails apps, and it is dirty and inefficient, a real pain in the ass, especially compared to the joy of doing most other things with Ruby/Rails. The failure of multi-app Rails is documented by the plethora of hacks used to emulate multi-app behaviors: generators, engines, appable plugins, and the multi-app routing plugin.&lt;/p&gt;

&lt;p&gt;The point of this post is not to rip on rails, it's just what I'm primarily using, and I would love to see other Ruby web frameworks such as merb, ramaze, and the micro-frameworks think about multi-app while they can still make major changes. Ruby is powerful enough to elegantly enable multi-app configurations.&lt;/p&gt;
&lt;h2&gt;What sucks about multi-app integration right now&lt;/h2&gt;

&lt;h3&gt;Redundant css and js&lt;/h3&gt;

&lt;p&gt;You send a new copy of prototype.js when switching between your core app, beast, and mephisto for example. You duplicate CSS as well. To avoid that you end up futzing around with deployment managers (capistrano) to make one app use the other's css and js in production.&lt;/p&gt;

&lt;h3&gt;Duplicate models&lt;/h3&gt;

&lt;p&gt;You have to duplicate models to access resources across the separate apps, or set up SCM, symlink hacks for versioning. Ugly, and suckage for dev / deployment differences.&lt;/p&gt;

&lt;h3&gt;Shitty routing&lt;/h3&gt;

&lt;p&gt;You end up using hacks and the web server instead of the app's router to resolve your routing. It's less powerful and in the wrong place. Now there is the multi-app routing plugin, which is just a hack to mitigate an underlying bigger problem. (It's cool for some use cases, sure, but still limited in capabilities)&lt;/p&gt;

&lt;h3&gt;Code scales poorly&lt;/h3&gt;

&lt;p&gt;Dumping all apps' M/V/Cs into one big app creates a cluttered project, and the project code doesn't scale. &lt;a href=&quot;http://www.caboo.se/articles/2007/10/17/multiple-apps-one-domain&quot;&gt;Here's a post by caboose's Courtenay&lt;/a&gt; hinting at that the rails directory structure struggles with large apps. Having &quot;eighty controllers&quot; should not be a reason for having to split a project into two completely separate projects, maintaining separate deployments, etc.&lt;/p&gt;

&lt;p&gt;In a way, the Rails folder structure is backwards, e.g. I can namespace my M/V/Cs but that means I have pieces of a semantically related structure (an app) in 3 places instead of one. When I work on code, I mostly work on a subcomponent of the app, and not just in M or V or C. &lt;/p&gt;

&lt;p&gt;What I want is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/app1
  /model
  /view
  /controller
/app2
  /model
  /view
  /controller
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/model
  /app1
  /app2
/view
  /app1
  /app2
/controller
  /app1
  /app2
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Memory overhead&lt;/h3&gt;

&lt;p&gt;People on shared hosts and small VPSes don't have ram to throw around. Right now, with a rails site consisting of a core app, blog, and forum, I get 3 hefty rails processes, when I want just one. (I could then use two mongrels, save 1/3 ram and get better concurrency/basic load balancing (if one app gets hit much more than the other)).&lt;/p&gt;

&lt;h3&gt;Single sign-on and session/cookie sharing&lt;/h3&gt;

&lt;p&gt;This isn't too hard to solve in practice, but it's not necessary. There should be a auth/login app to drop in instead of the generator. Other apps then by convention use user and user_id as the hooks into the auth/login system, but they don't all duplicate it. The auth/login system can be whatever, as long as the interface to it is a user model and user_id as the hook. All that would be left to do to integrate it is to add associations and before_filters. This has been a big topic of debate in the beast forums, and frankly, it shouldn't be that integrating a rails app with beast (another rails app) is exactly as cumbersome as integrating it with a PHP forum engine.&lt;/p&gt;

&lt;h2&gt;Fighting objections - it's all about views&lt;/h2&gt;

&lt;h3&gt;Plugins already provide (80% of) this functionality&lt;/h3&gt;

&lt;p&gt;No they don't, and they shouldn't. Engines, appable plugins, and generators  are all trying to fix part but not the root of the multi-app problem.&lt;/p&gt;

&lt;p&gt;Most importantly, plugins have no views. Have your ever counted your LOC? Views make up &lt;em&gt;a lot of code&lt;/em&gt;, especially with ajax thrown in. For example, I want to be able to drop in a blog or comment system that includes ajax posting of comments by default, rather than me having to write all the views from scratch. Plugins are fantastic for what they're designed for, but multi-app is not their use case.&lt;/p&gt;

&lt;h3&gt;High level components don't work&lt;/h3&gt;

&lt;p&gt;DHH is a declared opponent of components (or at least was, given that the quoted statements are over 2 years old). (see &lt;a href=&quot;http://www.loudthinking.com/arc/000407.html&quot;&gt;here&lt;/a&gt; and &lt;a href=&quot;http://weblog.rubyonrails.com/2005/11/11/why-engines-and-components-are-not-evil-but-distracting/&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;His experience is based on a failing high level parameterized component architecture in java. But the components he's talking about are different from multi-app. I'm not saying that you can just drop in a bunch of components and wire them together with a few parameters. I'm saying, get canonical code (e.g. a basic blog engine) and adapt it to your needs in a way that's cleaner and more maintainable/reusable than a generator's output or nested plugin stuff like engines or appable plugins.&lt;/p&gt;

&lt;p&gt;Also, David's experience was based on working in a java shop, but Ruby is much more concise than Java, and modifying a forum engine in Ruby isn't too bad, especially if its code layout follows a canonical layout such as the standard rails app structure.&lt;/p&gt;

&lt;h3&gt;Ruby/Rails makes it so easy to write from scratch, why bother?&lt;/h3&gt;

&lt;p&gt;Why would you need this stuff, if Ruby/Rails make it so easy to create a blog engine from scratch. DHH did it in 10 minutes in his video, Akita in 20 minutes. Did they really?&lt;/p&gt;

&lt;p&gt;It's like saying &quot;I can write a digg clone in 20 minutes.&quot; You can write something that provides the most basic functionality, but it's not a digg clone. You know why? UI, UI, UI. User interface is 80% of the value of an app for the end user, and right now there is no reuse of great UI design, which is a shame, because UI design is hard, and a lot of people would benefit from leveraging great UIs. I'd rather drop a mephisto-lite into my project than rewrite it from scratch to &quot;meet my app specific needs&quot;. And I want to do it without mixing its code and my own apps code wildly all over the place (which just creates SCM headaches).&lt;/p&gt;

&lt;h2&gt;What could multi-app look like?&lt;/h2&gt;

&lt;p&gt;The one framework I found that gets multi-app mostly right is Python's &lt;a href=&quot;http://www.djangoproject.com/documentation/tutorial01/&quot;&gt;django&lt;/a&gt;. It's great to be able to drop in a basic blog or forum engine that includes views/ajax, etc.&lt;/p&gt;

&lt;p&gt;At the very least, it makes utter sense to have common routing, css, javascript for a collection of apps in a site.&lt;/p&gt;

&lt;h3&gt;DRY up the suckage described above&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CSS, JS, models&lt;/li&gt;
&lt;li&gt;Sessions/cookies&lt;/li&gt;
&lt;li&gt;Routing&lt;/li&gt;
&lt;li&gt;(Single sign-on)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Rough idea for a project/app layout&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;/app_root
    /config (global configuration, affects all apps)
    /public
        /js (main app default)
        /css 
        /blog/js (blog specific)
        /blog/css
        /forum/js
        /forum/css
    # These are the apps that would be dropped into the application
    # Test and spec folders would be moved into the app folders, so
    # that each app can have its own test suite
    /app (The default main app)
    /blog (Full app with tests, etc., minus config, public)
    /forum (same thing)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;How to adjust routing&lt;/h3&gt;

&lt;p&gt;Routing could simply add a an 'app' level :app/:controller/:action/:id =&gt; http://mysite.com/forum/post/view/1&lt;/p&gt;

&lt;h2&gt;Problems to address&lt;/h2&gt;

&lt;h3&gt;Layouts and css&lt;/h3&gt;

&lt;p&gt;How to avoid layout duplication, and where to put app-specific css. I would put css in public/css/#{app_name}/default.css, and then for deployment join the css files. This would also require some name-spacing conventions of css to avoid collisions/overrides. I haven't fully thought through how to do a DRY layout structure.&lt;/p&gt;

&lt;h3&gt;DB table name collisions&lt;/h3&gt;

&lt;p&gt;I like django's solution of prefixing tables with the app name, e.g. a posts model in a blog and a forum app would map to the following tables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blog_posts&lt;/li&gt;
&lt;li&gt;forum_posts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This could be easily done by using the ORMs' table prefix methods, and could be automated, dealt with by convention.&lt;/p&gt;

&lt;h3&gt;Different apps being tied to different versions of the framework&lt;/h3&gt;

&lt;p&gt;What if my core app runs on edge, but my dropped-in mephisto-lite relies on Rails 1.2.x. Since I'm now running within the same process, this wouldn't be possible AFAIK, but the tradeoff is still worth it. Especially if you reuse a lot of your own internal apps. It might even lead to better maintained apps.&lt;/p&gt;

&lt;p&gt;I made the assumption of everything running in one process before, but that wouldn't necessarily have to be the case. Apps could run in their own processes with their own version of the framework, but I still have a smart wrapper around them for routing, etc.&lt;/p&gt;

&lt;h3&gt;Apps use different ORMs or databases&lt;/h3&gt;

&lt;p&gt;I haven't thought through this one too much, but it's even conceivable that apps could use different ORMs to talk to the database, or even use separate databases. I would probably have a global default db config, with possibilities for apps to override them. That might make the framework startup process overly complex, so I'd even be fine if all apps would have to use the same ORM/db. (Side note: Multi-db is still another unsolved challenge for most Ruby web frameworks).&lt;/p&gt;

&lt;h3&gt;Some folder locations might be contentious&lt;/h3&gt;

&lt;p&gt;Should /lib be global or per-app? Per-app keeps things more in one place and allows different apps to use different versions of the same library if necessary. Perhaps a structure of /lib/app_name would solve this in an elegant way.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;There is movement in the Ruby web framework space with new frameworks hitting the scene. &quot;The balls are in the air&quot;, and now is the time to bring up ideas for change. Rails has been and still is a fantastic yardstick by which to measure web frameworks, but Rails has warts too, and sometimes Rails is starting to feel a bit pudgy, like a &quot;Ruby Struts&quot; (which is amazing, because Rails is at least an order of magnitude better than Java Struts, it just shows how much progress is being made.)&lt;/p&gt;

&lt;p&gt;I talked about multi-app in this post based on my personal experience with Rails. Rails is fantastic, but I don't think they would incorporate a clean multi-app setup, but I'm hopeful that the new kids on the Ruby web framework block (like merb, ramaze, sinatra, et al.) will think hard about if and how to incorporate multi-app capabilities. Especially some of the micro-frameworks could scale very nicely (code management and deployment-wise) by clustering small, light apps together (like a bliki for example).&lt;/p&gt;

&lt;p&gt;I hope to stimulate a healthy, productive, and civilized discussion with this post. Hopefully, at least one framework will incorporate multi-app capabilities. Whichever Ruby web framework will end up with a clean multi-app setup will be the one I'll be using.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2007-12-10:7</id>
    <published>2007-12-10T11:55:00Z</published>
    <updated>2007-12-10T12:13:12Z</updated>
    <category term="merb"/>
    <link href="http://ducktyped.com/2007/12/10/merb-startup-problems-dies-after-compiling-routes" rel="alternate" type="text/html"/>
    <title>Merb startup problems: dies after "Compiling routes.."</title>
<content type="html">
            &lt;p&gt;I was so excited to play around with merb again. I just checked, and the first version of merb I used to prototype an app was 0.0.8 about a year ago. But I was so bummed out that after wanting to be all proper and upgrading all my gems, merb stopped working, no errors, no logs, no debug info, nothing.&lt;/p&gt;


	&lt;p&gt;After asking on &lt;span class=&quot;caps&quot;&gt;IRC&lt;/span&gt; (impossibly late at night) without any luck, I dove into the (beautifully clear and manageable) source and figured out that the &#8216;parsetree&#8217; gem was required, but not installed. So a quick &lt;code&gt;sudo gem install parsetree&lt;/code&gt;, was all that I needed, and I&#8217;m back in business.&lt;/p&gt;


	&lt;p&gt;After I realized that parsetree was to blame, a quick search brought up the same problem addressed and solved on the Ruby mailing list: &lt;a href=&quot;http://www.ruby-forum.com/topic/132766&quot;&gt;http://www.ruby-forum.com/topic/132766&lt;/a&gt;. But without knowing that the problem is parsetree related, how would you find this post. So again, for the crawlers &lt;b&gt;merb 0.4.1 stops after &#8220;Compiling routes..&#8221;&lt;/b&gt;&lt;/p&gt;


	&lt;p&gt;I can&#8217;t wait to get some real work done now. :)&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2007-07-02:6</id>
    <published>2007-07-02T10:57:00Z</published>
    <updated>2007-12-10T12:17:00Z</updated>
    <category term="coding environment"/>
    <link href="http://ducktyped.com/2007/7/2/set-up-ie-testing-on-localhost-using-parallels-on-os-x" rel="alternate" type="text/html"/>
    <title>Set up IE testing on localhost using Parallels on OS X</title>
<content type="html">
            &lt;p&gt;After an extensive hunt for a low-hassle solution for testing my local development rails applications in Internet Explorer using Parallels, I finally found &lt;a href=&quot;http://www.maintainablesoftware.com/articles/rails_internet_explorer_and_parallels&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;This is by far the most straightforward way and clearest writeup to get this development plumbing out of the way. It uses Bonjour for Windows so that you can access your rails apps with something like &lt;code&gt;mymachine.local:3000&lt;/code&gt;. Done! Now back to actual coding.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2007-06-16:2</id>
    <published>2007-06-16T10:54:00Z</published>
    <updated>2007-12-10T12:17:20Z</updated>
    <category term="coding environment"/>
    <link href="http://ducktyped.com/2007/6/16/get-svn-changesets-by-rss" rel="alternate" type="text/html"/>
    <title>Get SVN changesets by RSS for any public repository</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://subtlety.errtheblog.com/&quot;&gt;Subtlety is a beautiful thing&lt;/a&gt;. Just enter the repository&#8217;s url and add the resulting subtlety link to your feed reader. I&#8217;ve never enjoyed reading changesets so much. I actually follow projects now without missing anything.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://ducktyped.com/">
    <author>
      <name>ben</name>
    </author>
    <id>tag:ducktyped.com,2007-06-12:1</id>
    <published>2007-06-12T08:09:00Z</published>
    <updated>2007-12-10T12:15:28Z</updated>
    <category term="rails"/>
    <link href="http://ducktyped.com/2007/6/12/how-to-change-databases-using-ruby-on-rails" rel="alternate" type="text/html"/>
    <title>How to change databases using Ruby on Rails</title>
<summary type="html">&lt;p&gt;I was running a mysql 4.1 db that kept screwing up my unicode, so I decided why not double version numbers and move to postgresql 8.2. Great idea in theory, but a pain in the ass in practice. The sql dumps of the different &lt;span class=&quot;caps&quot;&gt;DBMS&lt;/span&gt; are incompatible, especially booleans causing trouble. The scripts I found were pretty much useless, so I was stuck until I came across the idea of using rails to export the db to yaml and then re-import it into the new db.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;I was running a mysql 4.1 db that kept screwing up my unicode, so I decided why not double version numbers and move to postgresql 8.2. Great idea in theory, but a pain in the ass in practice. The sql dumps of the different &lt;span class=&quot;caps&quot;&gt;DBMS&lt;/span&gt; are incompatible, especially booleans causing trouble. The scripts I found were pretty much useless, so I was stuck until I came across the idea of using rails to export the db to yaml and then re-import it into the new db.&lt;/p&gt;
&lt;p&gt;This sounds very elegant in theory, but there are still a few pitfalls. &lt;a href=&quot;http://blog.leetsoft.com&quot;&gt;Tobias Luetke&lt;/a&gt; posted &lt;a href=&quot;http://blog.leetsoft.com/2006/5/29/easy-migration-between-databases&quot;&gt;how he did it&lt;/a&gt; and provided a very useful rake task that became the basis for my approach. For good measure I threw &lt;a href=&quot;http://drnicwilliams.com/&quot;&gt;Dr. Nic&#8217;s&lt;/a&gt; &lt;a href=&quot;http://magicmodels.rubyforge.org/magic_model_generator/&quot;&gt;magic model generator&lt;/a&gt; in the mix to allow for very powerful and flexible migrations, even if your application doesn&#8217;t define models for all tables, e.g. when you have several apps using the same db.&lt;/p&gt;


	&lt;p&gt;The following is my 10-step program for database migration bliss.&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Set up the basics
  &lt;pre&gt;&lt;code&gt;
  sudo gem install magic_model_generator
  rails db_migration_app
  cd db_migration_app
  &lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;Download the &lt;a href=&quot;http://thenakedbrain.com/assets/2007/6/12/backup.rake&quot;&gt;backup.rake&lt;/a&gt; task and copy it to lib/tasks/&lt;/li&gt;
		&lt;li&gt;Connect to your production db in config/database.yml. This is also a good time back up your db before you ruin things with jittery fingers and then blame me.&lt;/li&gt;
		&lt;li&gt;With the db set up properly, get the schema and magic models ready
  &lt;pre&gt;&lt;code&gt;
  RAILS_ENV=production rake db:schema:dump
  RAILS_ENV=production ./script/generate magic_model
  &lt;/code&gt;&lt;/pre&gt;
  (Just for kicks, you can inspect your entire db through the rails console via
  &lt;span class=&quot;caps&quot;&gt;RAILS&lt;/span&gt;_ENV=production ./script/console)&lt;/li&gt;
		&lt;li&gt;[OPTIONAL] Add any tables that should not be dumped/restored to the array in the rake task&#8217;s &lt;code&gt;interesting_tables&lt;/code&gt; method. &lt;code&gt;schema_info&lt;/code&gt;, &lt;code&gt;sessions&lt;/code&gt;, and &lt;code&gt;logged_exceptions&lt;/code&gt; are excluded by default.&lt;/li&gt;
		&lt;li&gt;Let&#8217;s do some dumping. This may take some time, depending on your db size.
  &lt;pre&gt;&lt;code&gt;
  RAILS_ENV=production rake db:backup:write
  &lt;/code&gt;&lt;/pre&gt;
  At this point you have all your tables&#8217; data in yaml format in db/backup/*.yaml.&lt;/li&gt;
		&lt;li&gt;Now change your database.yml to the new, empty db (e.g. your brand new pg db). Don&#8217;t mess this up, because the next step will completely wipe whichever db is defined as the production db.&lt;/li&gt;
		&lt;li&gt;Import the yaml data into the new production db.
  &lt;pre&gt;&lt;code&gt;
  RAILS_ENV=production rake db:backup:read
  &lt;/code&gt;&lt;/pre&gt;
  This also runs rake db:schema:load, and restores the correct schema_info.&lt;/li&gt;
		&lt;li&gt;[EXTRA &lt;span class=&quot;caps&quot;&gt;CREDIT&lt;/span&gt;] If you migrate to postgresql, fix your sequences in one easy step with the following rake task I created:
  &lt;pre&gt;&lt;code&gt;
  RAILS_ENV=production rake db:backup:set_sequences
  &lt;/code&gt;&lt;/pre&gt;
  If you want to check the sequence number in psql, run &lt;code&gt;select last_value from table_name_id_seq;&lt;/code&gt; (where table_name is your table&#8217;s name)&lt;/li&gt;
		&lt;li&gt;Lastly, make sure you don&#8217;t forget to adjust your actual application&#8217;s database.yml to point to the new db.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Enjoy your newfound freedom from the stranglehold of your old database. :)&lt;/p&gt;
          </content>  </entry>
</feed>
