This is partially for me in the future just in case I'm stuck doing this again, and it's partially for the lone googler in the future who comes by needing a quick fix.
So, the short version:
Grab the 64bit version from MySQL ("Mac OS X 10.5 (x86_64)"). Easiest way is to grab the DMG, use the installer, and then add the preference pane.
It's probably helpful to add an alias for mysql in your ~/.profile:
alias mysql=/usr/local/mysql/bin/mysql
alias mysqladmin=/usr/local/mysql/bin/mysqladmin
Grab your Leopard DVD and install Xcode if you haven't already... it'll help you compile some of the native C code involved with the MySQL gem.
Rock this:
sudo env ARCHFLAGS="-Os -arch x86_64 -fno-common" gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
That'll build your MySQL gem for you. Most of the issues with errors like "lazy symbol binding failed" are the result of not setting those architecture flags; something with Leopard pushing multiple architectures but MySQL expecting only one.
Those are the main sticklers; if I missed a step along the way it's probably easy enough that a quick Googling would solve. Kudos to http://cho.hapgoods.com/wordpress/?p=158 and its commenters in helping figure out some of those pesky details.
I've been using Ruby on Rails for a good year and a half now, but something I still remember from when I was just getting started was the lack of discussion about SQL injection or XSS issues. This isn't very surprising; in any language or framework the last thing you explain to beginners is a rousing study on security concerns. It's kind of sad, really, when you think about it. But so is life. Let's look at code.
Your basic ActiveRecord find goes something like this:
@articles = Article.find(:all)
That'll find all of your articles and populate them into @articles. Cool beans. Say you want to grab all the articles that are titled a certain way, which you have access to via params[:title]. There's a few ways of doing this. One way is to add :conditions.
@articles = Article.find(:all, :conditions => "title = #{params[:title]}")
So what you're doing is grabbing :title from your parameters and then directly tossing it in your query. Repeat with me: bad code. This is vulnerable to what's called an SQL injection attack, meaning anyone can come along and look for a post with the title of:
1; DROP TABLE super_cool_table;
So, like, don't do this.
One solution is to use ActiveRecord's magic, super-cool finder:
@articles = Article.find_by_title(params[:title])
This is fine. Rails automatically makes sure that any arguments you pass in won't be able to inject arbitrary SQL. For a bit more flexibility, I go the following route:
@articles = Article.find(:all, :conditions => [:title => params[:title]])
...or even:
@articles = Article.find(:all, :conditions => ["title = ?", params[:title]])
These are both a-okay. Rails sanitizes the parameters in each of these scenarios, so you can rest assured that you're not wide open to some ugly attacks.
I recently discovered a XSS hole in PayPal's own website, which theoretically would let me set up an attack that would let me steal your cookies, hijack your PayPal session, and do lots of Bad Things to your PayPal account and linked credit cards and bank accounts (probably involving hookers, a flight to Panama, and a fancy new yacht). (By the way— if anyone has a better idea of getting in touch with PayPal, let me know... it's surprisingly difficult to sift through regular customer support with issues like this.)
Anyway, I digress. For more information on XSS, check out the ever-popular Wikipedia article. You're here to combat XSS anyway, right? Let's get started.
In your views:
<%= h @article.title %>
That's it. The method "h" escapes any HTML that might be in your article's title that a wayward user might have submitted.
Granted, it's a bit of a pain in the ass. Django decided to auto-escape your values by default, and Rails does not. And the fun with XSS is that if you miss one of those little h method calls, well, you're screwed.
There's a few ways around that, though. One is to make sure you sanitize user input on the way into your app, so when you call it later on you know that you're safe. Another somewhat unequal way of doing things while maintaining interactivity (like embedded links and images) is to do the same thing I'm doing on this blog for its comments: allow users to use Markdown (or Textile) instead of HTML.
Another option is to go the plugin route and let it handle sanitization for you:
Admittedly this will impact a very minor number of you out there, but I've been enjoying my newfound iPhone 1.1.3 capabilities, specifically in terms of fun new icons I can toss on my iPhone's desktop for a quick link to a website somewhere.
I started looking around, trying to see which one of the sites I normally frequent have super-special iPhone/iPod Touch icons around (like this fantastic site). It's a bit of a pain to do it all one at a time, so I looked at my feed reader.
NetNewsWire has an OPML export option, and I'm sure other readers do, too. I figured, hey, let's just try to see if I can parse that export to see which of my subscribed feeds have WebClips. It's a bit of a hack job since I only wanted to spend 10-15 minutes working on it, but it works decently for what it needs to do (and I had some help which shaved a few minutes off of the process).
require 'rubygems'
require 'hpricot'
def valid_url?(url)
uri = URI.parse(url)
http_conn = Net::HTTP.new(uri.host, uri.port)
resp, data = http_conn.head("/apple-touch-icon.png" , nil)
resp.code == "200"
end
filename = ARGV.first
doc = open(filename) { |f| Hpricot(f) }
(doc/"outline[@htmlurl]").each do |item|
url = item.attributes['htmlurl']
puts url if valid_url?(url)
end
Nothing really groundbreaking here- just toss that in a file and then pass it the name of your OPML file, presuming they're both in the same directory. It'll then trawl through your subscriptions and spit out any domains that have WebClip icons. So, type something like
ruby webclip.rb subscriptions.opml
This also assumes Hpricot is installed
sudo gem install hpricot
Hooray. iPhone home screen icons.
When working with Rails, you can really end up with a lot of things going on at once. When I'm coding, I'll usually have Terminal open with my Mongrel server instance running, a tab with autotest with RedGreen and Growl integration running, and another tab open for me to run other script/generate commands or script/console commands. On top of that, I'll also have my trusty TextMate instance running in a different space and Safari actually running the app in a different space. It's a rather sweet setup, but it's a pain to set it up in the beginning. Naturally, you want all of this to be as painless as possible so that it's just easier to jump in and code when you want to.
I looked into pretty much every way to go about automating this. There's plenty of ways to give it a shot, too- first was Quicksilver and trying to tie together a number of apps in one hotkey grouping, but it didn't give me enough control over running commands in Terminal (specifically with keeping tabs intact).
Next up was Terminal itself, specifically in terms of Terminal's Window Groupings, which ended up really sucking. It lets you save specific numbers of tabs in a certain window, but it doesn't let you automatically run different commands in each tab (you can run a generic command, like "cd ~/railsapp" for each tab which was partway there though). I even went so far to dig into the Terminal .term XML files to manually try to get it to work, but the changes didn't stick.
AppleScript was the next idea, of course. I'm no AppleScript guru, but I know enough to be dangerous. The problem was that Terminal, though much improved in Leopard, still didn't offer a lot of comprehensive ways via AppleScript to modify tabs and run commands.
I even looked at giving Ruby a shot, mostly through libraries like RubyOSA. It basically hooks Ruby into regular apps on your OS X install, so you can use Ruby to control iTunes, for example. Again, though, as it builds upon AppleScript, you run into the problem of getting a finer control of scripting Terminal without definitive AppleScript dictionaries.
After all of this, adjusting my bash profile ended up being the simplest, cleanest, and fastest way to tackle this problem. It's an area I really haven't gotten into very much, but luckily it's really quick to dive into for this simple problem.
Basically you set an alias for longer commands in your profile. If you want to handle it yourself, jump into your profile (create it if the file doesn't exist):
vi ~/.profile
From that point, it's really simple. Set an alias and type in the longer command. For example:
alias ss='script/server'
alias sc='script/console'
alias a='autotest -rails'
...and so on. I have a separate alias to change the directory to a specific Rails project:
alias gt='cd /path/to/railsapp'
alias gtss='gt; ss'
So it's pretty easy for me to use Quicksilver to open Terminal, type "gtss" to start Mongrel, command+T for a new tab, hit "gta" to start autotest, and so on. I can probably refine the process even further by using the "run command in Terminal" bundle within Quicksilver to consolidate the first few steps, too. As a final helpful command, you can start up TextMate and Safari, too:
alias gtm='gt; mate .; open http://localhost:3000'
It's not the perfect solution yet (I'd love to hit one Quicksilver command and spawn 3-4 Terminal tabs, Safari, and TextMate all at once), but I can start up everything in a few seconds compared to half a minute or more than doing it all manually. The result is that I can hop into my development environment much quicker, which means it's a lot easier to get down to business when I need to.
A quick little plug for one of the coolest screencast out there: Railscasts. Railscasts is similar to PeepCode's screencasts, which are kind of "the" Ruby on Rails video tutelage out there. The difference is that Railscasts are free and superficial. And I mean superficial in a good way: instead of an hour-long focus on a deep, rich subject, Ryan at Railscasts is able to bring small tidbits of Railsy goodness to you in a couple minutes. It's the kind of stuff you can do right now to help improve your coding style, productivity, and so on. Plus, it's really easy to spare a couple minutes to learn something new. And, for those of you new to the game, they're not quite basic into screencasts, but they're definitely not advanced material, so it's pretty easy to wrap your head around them.