6200 comments
2357 subscribers
Follow me on Twitter (@sachac)
Subscribe! Feed reader E-mail

Rails: Exporting data from specific tables into fixtures

Rails is pretty darn amazing. There are plenty of gems (Ruby packages) that provide additional functionality. They’re like Drupal modules, except with more customizability (not just hooks) and fewer pre-built administrative interfaces (you win some, you lose some).

For example, the client asked me, “Can we edit the static content?” Now if I had asked about this as a requirement at the beginning of the project, we might have gone with Drupal instead–although the Rails Surveyor still feels cleaner than a CCK-based survey type, so we might’ve stayed with Rails.

Anyway, we were well into Rails now, so I looked for a content management system that I could integrate into the Rails 3-based website. After some experimenting with Refinery CMS (looks slick, but couldn’t get it to do what I wanted) and Comfortable Mexican Sofa (looked pretty geeky), I settled on Rich CMS. I nearly gave up on Rich CMS, actually, because I’d gotten stuck, but the web demo helped me figure out what I needed to do in order to enable it.

We’re still emptying and reloading the database a lot, though, so I wanted to make sure that I could save the CmsContent items and reload them. I didn’t want to back up the entire database, just a table or two. There were some gems that promised the ability to back up specific models, but I couldn’t figure it out. Eventually I decided to use the table-focused Rake code I saw in order to export the data to fixtures (seems to be based on code from the Rails Recipes book).

task :extract_fixtures => :environment do
  sql  = "SELECT * FROM %s"
  skip_tables = ["schema_info"]
  ActiveRecord::Base.establish_connection
  if (not ENV['TABLES'])
    tables = ActiveRecord::Base.connection.tables - skip_tables
  else
    tables = ENV['TABLES'].split(/, */)
  end
  if (not ENV['OUTPUT_DIR'])
    output_dir="#{RAILS_ROOT}/test/fixtures"
  else
    output_dir = ENV['OUTPUT_DIR'].sub(/\/$/, '')
  end
  (tables).each do |table_name|
    i = "000"
    File.open("#{output_dir}/#{table_name}.yml", 'w') do |file|
      data = ActiveRecord::Base.connection.select_all(sql % table_name)
      file.write data.inject({}) { |hash, record|
        hash["#{table_name}_#{i.succ!}"] = record
        hash
      }.to_yaml
      puts "wrote #{table_name} to #{output_dir}/"
    end
  end
end

Being a lazy programmer who doesn’t want to remember table names, I also defined the following Rake tasks:

task :save_content => :environment do
  ENV["TABLES"] = "cms_contents"
  Rake.application.invoke_task("myproj:extract_fixtures")
end
task :load_content do
  Rake.application.invoke_task("db:fixtures:load")
end

Then I can call rake myproj:save_content and rake myproj:load_content to do the right thing. Or rather, my co-developer (a new IBMer – hello, Vijay!) can do so, and then check his work into our git repository. =)

Now we can re-create the development database as often as we’d like without losing our page content!

2011-04-24 Sun 16:29

Short URL: http://sachachua.com/blog/p/22215

On This Day...

  • 2013: Hacking my motivation for workouts — There was a recent Lifehack.org post on tying something you love to workouts so that you feel more motivated. It’s [...]
  • 2012: Tweaking my introduction, focusing on sketchnotes — One of the things I like about meetups is the opportunity to test introductions. With all the different things I [...]
  • 2010: A letter to my 8-year-old self — Dear 8-year-old Sacha, You might not believe me, but your interest in computers will lead to making lots of good friends. [...]
  • 2009: Putting together an inspiration board — I asked one of my assistants to track down envelope images for the sewing patterns I have, and to send [...]
  • 2009: Yes, I work at a big company — Sara Morgan e-mailed me to ask if I could tell any stories about self-employment for inclusion in her upcoming book, [...]
  • 2008: Gen Y Growing Up: My first chat with a financial planner — Another milestone! Today, I consulted a financial planner for the first time. I’d been meaning to find a financial planner [...]
  • 2008: Kaizen Presentations: Web 2.0 and the University — I’m still buzzing from the first client teleconference presentation I made. I gave a brief overview of Web 2.0 and [...]
  • 2007: Money management for the next stage in your life — I attended a personal finance seminar by Ellen Roseman, a Toronto Star columnist and University of Toronto alumna. I’ll write [...]
  • 2007: Week past, week next — Last week was a week of thresholds. I’ve started doing my usability tests, and I’m not going to stop until I [...]
  • 2005: Structuring content — What do I write about that other people might find useful/interesting? Emacs-related stuff Personal information management and productivity ShortStories and FlashFiction Teaching reflections (haven’t [...]
  • 2005: Big, Hairy, Audacious Goals — My Big, Hairy Audacious Goals (BHAGs) are: Revolutionize computer science education by making it highly individualized and experiential. Become a [...]
  • 2003: Notebook cooling pads — Steve Barr linked to http://www.xoxide.com/noco.html and http://www.hightekpc.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=43&page=1 in a wear-hard post. Hmmm. Notebook cooling pads…
  • 2003: planner-el is now apt-gettable! — After I ran dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz dpkg-scansources . /dev/null | gzip -9c > Sources.gz in my ~/notebook/emacs/planner directory [...]