Posts Tagged: ruby on rails


20
Jan 11

Connecting a Windows VM to a Mac-based localhost Ruby on Rails site (Passenger)

Supporting Internet Explorer for your web app is a pain. At least, trying to test your Ruby on Rails (or other localhost-based site) in IE while developing on the Mac should be easy, given the prevalence of virtual machines. Right?? You’d think. However, trying to setup our front-end developer to access a local instance of Passenger running on Mac OS X from a Windows VM proved to be more of an issue than it needed to be. Adding to this, most of the top Google results for relevant keywords for this configuration made the process more overly difficult than it needed to be.

So, to help ease your pain in testing your Mac-based Rails site from a Windows virtual machine, here is an easy configuration for the three main VMs.

We need to do two main things:

  1. Trying to serve port-based or subdomain-based sites over to the Windows VM is going to be more challenging. Let’s make things easy – we’ll set the default http://localhost site for our Mac to our Rails site.
  2. We need to get the VM’s network to communicate with the Mac’s network correctly so that we can access this site.

On my team, we’re using Passenger on the Mac (running on top of the Mac’s base install of Apache). We’re using Passenger Pane to configure Apache easily. We also have this hooked into RVM, but that won’t be relevant to what we’re doing here. For the purposes of this post, I’ll assume that you have Passenger successfully serving a site that you can access via http://somedomain.local I’ll also assume that for whichever VM you’re opting to use, you have Windows installed and running in it.

** Do yourself a favor. Make sure that VM Ware Tools, Parallel Tools, or VirtualBox Guest Additions are installed – this ensures that the network connectivity will work as expected.

 

Let’s get http://localhost serving our Rails site

At the bottom of /etc/apache2/httpd.conf when using Passenger Pane, you’ll find the following configuration:

<IfModule passenger_module>
  NameVirtualHost *:80
  <VirtualHost *:80>
    ServerName _default_
  </VirtualHost>
  Include /private/etc/apache2/passenger_pane_vhosts/*.conf
</IfModule>

 

To make our Passenger site the default localhost site, go into passenger_pane_vhosts/, view the Apache config file for the site you want to be the default, and you’ll see something along the lines of the following:

$ cat yoursite.local.vhost.conf
<VirtualHost *:80>
  ServerName yoursite.local
  DocumentRoot "/Users/username/rails/yoursite/public"
  RackEnv development
  <Directory "/Users/username/rails/yoursite/public">
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

 

Copy the lines from inside the VirtualHost block and paste them back into /etc/apache2/httpd.conf so that it looks like the following:

$ cd ..
$ sudo mate httpd.conf
# Added by the Passenger preference pane
# Make sure to include the Passenger configuration (the LoadModule,
# PassengerRoot, and PassengerRuby directives) before this section.
<IfModule passenger_module>
  NameVirtualHost *:80
  <VirtualHost *:80>
    ServerName _default_
	####
	DocumentRoot "/Users/username/rails/yoursite/public"
	RackEnv development
	<Directory "/Users/username/rails/yoursite/public">
	  Order allow,deny
	  Allow from all
	</Directory>
	####
  </VirtualHost>
  Include /private/etc/apache2/passenger_pane_vhosts/*.conf
</IfModule>

 

Restart Apache by going to System Preferences > Sharing and uncheck & recheck Web Sharing.

Also, if you’re using VMWare Fusion or Parallels, note the IP address that’s shown here.

Configuring VirtualBox

Let’s start with Virtual Box, which was the biggest pain to configure. Not because there’s a lot of work, but because they one critical detail doesn’t seem to be well known (most of the posts you’ll read online try to guide you through using the command-line network configuration tool). I should note that this was my first real opportunity to use Virtual Box, having only used Parallels and VMWare Fusion beforehand. It’s a little rough around the edges in a few places, but overall very impressive.

1) First, ensure that network settings for VirtualBox should be set to NAT – no port forwarding needed

 

2) Now, here’s what took a while to dig up: VirtualBox connects http://10.0.2.2 to the Mac’s localhost (thanks to this forum post) That is, just typing that into IE within the VM should connect you to http://localhost running on the Mac.

 

Configuring Parallels

1) For Parallels, you want to make sure that your VM is running on a Shared Network.

 

2) If you’re setup with this network configuration, you should be able to directly access the local IP address of your Mac, as shown in the System Preferences > Sharing screen:

 

Configuring VMWare Fusion

1) VMWare Fusion is much like Parallels. Configure your VM to “Share the Mac’s network connection” via NAT.

 

2) If you’re setup with this network configuration, you should be able to directly access the local IP address of your Mac, as shown in the System Preferences > Sharing screen, as with Parallels.

Hopefully, if you’ve made it to this point, for your respective VM, you have IE accessing your Passenger-based site. Success!

 

Hopefully, at least now you’ll be able to spend your time on all of the issues that poor users confined to IE are suffering through and get bug fixing quickly.


24
Nov 10

Hey, what caused that ActiveRecord::ConnectionAdapters::TableDefinition:gooblygook on my table?!

Maybe you’ve run into this, too? You’re taking a look at the tables generated by your Rails migration and you see this really odd column.

#<ActiveRecord::ConnectionAdapters::TableDefinition:0x10245fd78>

Here’s another look:

Yuck!

Searching the web didn’t turn up much in this case, so I thought I’d post what I found when figuring out the root cause.

See the issue in this migration?

No? I didn’t the first time I looked, either.

It’s the comma – at the tail end of the last column definition before t.timestamps.

This little typo doesn’t look like much, but it’s the cause of that wacky column.

Here’s what the table looks like when you run the migration with the comma:

And here’s what it looks like when you fix your typo:

Ah! Much better.

As for creating a migration to fix this, I just resolved the typo and dropped the column manually. It’s a little difficult to script this because the column name will be different in each database, so, it’s some variation of this (the part in bold on each database that the original typo ran on):


ALTER TABLE `friendships` DROP `#<ActiveRecord::ConnectionAdapters::TableDefinition:0x10245fd78>`;

Hope this helps someone else avoid wasting time on this!


26
May 10

Quick fix for MacPorts Ruby version conflicts

After configuring MacPorts, I was running into an issue on my Mac with Ruby on Rails where ‘/usr/bin/env ruby’ was giving me a different version of ruby than the one which has my gems installed. This was an issue for trying to run the ruby scripts with the shebang according to the best practices (i.e. /usr/bin/env ruby). So, trying to run script/console or script/server gave me lots of headaches. This may be a simple fix, but hopefully this will help others with similar issues.

$ /usr/bin/env ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin10]
$ /usr/bin/ruby -v
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]

 

It took me a bit of fiddling and testing to figure it out, but I finally realized out that the MacPorts installation process had put its bin directories before the default bin directories. Ordering is fairly crucial – paths that are listed first take preference.

This is what I had after installing MacPorts:


export PATH=/opt/local/bin:/opt/local/sbin:$HOME/bin:$PATH:/usr/local/bin

This is the correct order (note – moved the /opt/local paths for MacPorts at the end to get things loaded in the right order):


export PATH=$HOME/bin:$PATH:/usr/local/bin:/opt/local/bin:/opt/local/sbin

With the order changed, now Ruby and Gem load from the same install (the MacPorts version of Ruby was loading overtop of the base Mac install).

Again, a simple fix, but hopefully, it might help someone running into the same issue.


12
Jan 10

Why is the user experience for adding Facebook apps so poor?

A friend linked me to a random promotions app on Facebook the other day and it stopped me in my tracks for a moment.  Unlike most apps I’ve seen, the first screen was something very interesting – it was actually inside the application itself and was not the not the lovely “Allow Access” screen that Facebook users are accustomed to.

This made me wonder – pretty much most of the biggest Facebook apps I can think of ask for permission before letting you do anything.  I understand why Facebook is protecting profile information, but as a developer, you can configure your initial app screen so as not to require permission to access content.  The promotions app did this and we’ve set it up for our application.

So, the question is – why are so many huge Facebook app developers happy with the poor user experience of having the “Allow Access” screen being the first thing that users encounter with their application?  Why not show a screen that gives you a better idea of what the app is and then if the users actually wants to use the app, then they would request access.  Is this simply a ploy for the publishers to get more “active users” and thus boost themselves in the AppData standings?  Or are Facebook users quickly becoming numb to releasing their private information and the age of privacy is really over, as Facebook’s Zuckerberg recently claimed?

FYI – for Rails developers using Facebook, it’s pretty easy to not require the Allow Access screen on your welcome controller or whatever serves as your landing screen.  Just skip the Facebooker ensure_app_installed before_filter and don’t make calls that try to access the user’s information:

skip_before_filter :ensure_app_installed

10
Jan 10

Collaborative Team Facebook Development

For as much as has been written regarding developing Facebook applications with Rails (which isn’t that much considering the staggering popularity of Facebook and Rails), there is even less written on developing Facebook applications in a team environment.

There are a couple of potential strategies. One of the few articles out there describes the challenges in developing apps as a team:

This sets up some challenges for a development team. First off, your application probably relies on Facebook services, meaning it can only be fully tested from within Facebook. This implies that the external Facebook server needs to be connected to your development server. Since many Rails developers run off their own development machine behind a firewall, this is potentially awkward. Similarly, the fact that the Facebook application has a single URL mapping makes it difficult for multiple developers to work on the same application without tripping over each others’ work.

The author goes on to discuss the solution that their team is using, consisting of a series of Rake tasks and a staging server to facilitate testing in a team environment.

The other option, which is supported natively by Facebooker, is using an SSH tunnel from the local development workstation to an intermediary server and having the Facebook app point at that server. (This necessitates having an understanding IT team that doesn’t lose that much sleep over some open ports…) The SSH tunnel is discussed by many of the Facebooker tutorials available (here, here, and here).

We adapted the SSH tunnel strategy to our team environment. Each developer will have a development Facebook app and then will point that to their assigned port on our staging server. Then they can tunnel into the staging server from their local workstation. In this way, everyone can be testing their work independently without needing to coordinate deploys through to a staging and central test application. The below diagram illustrates this.

Ok, so we have our plan, but how to go about setting this up? In particular, the other tutorials don’t talk about what you do or do not have to do on the server side. In truth, the tunnel is fairly easy to configure and seems to be working well.

On the server side, the key is making sure that the ports you need aren’t blocked and are accessible for purposes of the tunnel. No need to configure virtual hosts or mongrels – the staging server is a simple relay. You will probably need to configure SSH to turn on GatewayPorts. That’s just a couple of quick steps:

  • sudo vi /etc/ssh/sshd_config
  • Find the line GatewayPorts if it’s there.
  • Change or add to: GatewayPorts yes
  • Restart SSH: sudo /etc/init.d/ssh restart

(based on other blog posts I came across, be sure to indicate GatewayPorts yes and not GatewayPorts clientspecified)

Now, via Facebook’s Developers application, each developer should configure an application for testing purposes. Set the Canvas Callback URL to http://your.stagingserver.com:####/ (Facebook requires that you have a trailing slash) and you should be good to go. Depending on your application, you may need to configure other settings (other callback URLs or iFrame/FBML, but the canvas callback URL is the primary setting. Make a note of the API key and the secret key.

Finally, we can setup the tunnel. Go into the Rails app that you pulled down from your Git repp and edit config/facebooker.yml. Add in the API key and secret key from your development application you just configured. For the canvas page name, enter the name of your application, as configured on Facebook. Then change the callback URL to the same URL the app is configured for: http://your.stagingserver.com:####/ (again, trailing slash!). Then enter the SSH username and hostname for your staging server, save the file, and you should be good to go.

At this point, you should be able to start your development server (ruby script/server) and then start the tunnel (rake facebooker:tunnel:start). If you’re on Windows, be sure to run these commands through Cgywin. At this point, you should be able to go to http://apps.facebook.com/yourappname and see your development app. While the app is loading, you should also see the SSH command window and the Ruby Webrick/Mongrel window showing the incoming connection and the Rails system handling the requests.