Quick Start with Sequel 3 in Rails 3
This guide is using Rails 3.2.6 and Sequel 3.37.0. If you're using a different version, these instructions may not quite apply.
Edit: realized this morning the title was ambiguous, so I updated it to reflect the Sequel focus.
Here's the easiest way to get going with Sequel in Rails:
AutoPull: you push, it pulls
So you use GitHub and some compiled language, but not everyone can or wants to compile the source, they just want the artifacts. I made a tiny app that aids in this sort of thing. If you have ever wanted to execute an event in Ruby in response to a push to a repo via GitHub's Post-Receive URL hooks, this is probably a good starting point.
Additionally, it doesn't have to just be used with GitHub (anything that can automatically hit a URL works), and it doesn't even have to be used for pulling down source -- it can send an email or something. Right now I'm using it for HydrateJS -- when I push some new CoffeeScript to GitHub, it automatically pulls and rebuilds the .js file on my server.
Time matcher for RSpec2
I've found myself reusing this matcher a bit for time-sensitive tests, so I thought I'd share it. It allows you to verify that a block took a certain amount of time to execute.
Ruby Monitor Basics, or, How the heck do I synchronize producers/consumers
Have you ever written something like this?
threads = [] threads < < Thread.new { something_slow } threads << Thread.new { something_really_slow } threads << Thread.new { go_take_a_coffee_break } threads.each {|t| t.join} puts "all done!"
This works fine, but...it's expensive to start up and stop threads (even green ones), and what if you instead used/needed Ruby's queue:
1 2 3 4 5 6 7 8 9 10 11 | require "thread" q = Queue.new q < < 3 << 10 << 10000 < 2352352 threads = [] 10.times do threads << Thread.new do num = q.pop # marker 1 puts "#{num}: " + calculate_fibonacci_for(num) end end |
For those of you who don't know, Queue is basically a (threadsafe) array that puts the calling thread to sleep if #pop is called on it while it's empty, and wakes it up again when it's not empty.
But how do we know when we're done? You can't call #join on all the threads; they never terminate because they're blocking on q. Here's where monitors come in.
ReReplay: Replay production traffic
Ever wonder if your change is going to slow down the website? "Performance impact will probably be negligible", you might say. Well, now you can know for sure. First, take a slice of your production logs and transform it into a particular format. Then run ReReplay with this snapshot to generate a baseline. Next apply your change, rerun ReReplay (sorry, too many re's?) and measure the difference!
Announcing Crow, a path-finding library in Javascript
Over the past few weeks I've been building out a clean and fast path-finding library in Javascript with a particular gaming site in mind, and I'm pretty happy with where it's at right now. If you're interested in at least one of: API design, Google Closure library, Google Closure compiler, or QUnit, then hit the jump for more. In the future, I'll cover Javascript (and object-oriented patterns), path-finding (breadth-first search, Dijkstra's algorithm, and A*), rake, games, and the embedded Sinatra+Bundler.
A brief introduction to Ruby, Sinatra, and Haml
Ruby and Sinatra make it ludicrously easy to make a webapp, but getting started, as with any new language or framework, can be daunting. By the end of this part, you'll have a simple template that talks back to you!
Destructors in Ruby? Not quite…
So I was curious to see how destructors work in Ruby, and...they don't. Or rather, the method we do have, ObjectSpace.define_finalizer, is rather restrictive. But it does leave a loophole -- the callback method receives an object_id.
Cool free hosted tools for your Ruby webapp
Some of these are obvious (i.e. get exceptional, hoptoad), many of these aren't Ruby-specific, but I thought it might be nice to put all these in one place, at least for my sake.
Exception tracking
Get Exceptional limit: 1 app
Hoptoad limit: 1 project, 2 users
Bug tracking:
there's github, of course, if you're already using that...
16bugs limit: 1 project
I'm not including full hosting platforms, like Google Code here, but you could use those, too
One-off emails (i.e. signup)
Sendgrid limit: 200 emails/day
GMail allows 500 emails/day, but doesn't offer all the doodads that Sendgrid does
Mailing list (i.e. newsletter)
Mailchimp limit: 500 subscribers, 3000 emails total a month
Customer Support
SnapABug limit: 10 reports/day
uservoice limit: 100 unique users/month
GetSatisfaction limit: 0 official reps, not hosted on your url
Analytics
There's a ton of options in this space, but I use:
Google Analytics limit: no limits, because it's The Goog
Clicky limit: 1 website, 3000 hits/day
Metrics, Monitoring
New Relic limit: no troubleshooting, optimization, etc
Tripwire (Alpha, no immediate signup) for tracking validation errors. limits not specified
User Avatar Hosting
Gravatar limit: none
Authentication
OpenID
RPX limit: up to 6 providers, instead of 12
Time tracking/invoicing
Harvest limit: 2 projects, 4 clients, 1 user
Help desk thing
Just kidding, couldn't find any free hosted help desk apps
Anything else I'm missing that every webapp needs?
Update 10/5/2010: added Tripwire
Design pattern/flow for building a website
So here's how I normally do things:
- Do as much of the models as possible in this first pass, skipping validation but including schema stuff
- Stick a couple things into the controllers that I think I'll need
- Build out some of the views, giving them some basic styles
- Revisit the models to add validation, helper methods
- Build out the rest of the views, give them real styles
- Muse about specs, then give up before starting
- Put more stuff into the controllers
- Iterate on random components until you're done
Needless to say, I'm getting to the point where my lack of organization kills my mini-projects before I hit step 4, sometimes even sooner than that. So I'm going to try a slightly more...conventional (or widely suggested, at least) approach:
- Create controllers with just enough information so that your pages will display. No setting variables yet or other logic!
- Fill out the views with as much HTML and fake data as you need. Site have a sign-in page? Leave a link to "force sign-in" the user that simply sets them to an authenticated state. All it should do is set a session variable
- Spec out the models. Don't check for validation yet, just check for core functionality, i.e. there is a User table, the first user has a name of Foo and email of [email protected], etc.
- Fill out your model code so that the specs pass -- this includes migrations with sample data (these can be removed in a later migration).
- Spec out your controllers/views.
- Fill out your controllers/views so they pass specs.
- Do the rest of the little things that need doing, like validation, error messaging, authentication, styling, etc.
- Revel in having finished a project.
Hopefully I'll get further than step 3 this way! I'm going to try to focus more on content/frontend instead of getting bogged down in the backend, and I want to actually write specs.
Any comments/suggestions?