Filed under Uncategorized

Rails Host Review – (the bad) HostingRails

I am currently working on a project for the City of Edmonton’s Apps4Edmonton contest.  When we initially started looking for hosts we made the decision that we would use a cheap host for our initial deployment, and then migrate over to something faster when it was justified.  Our site Alertzy is mostly a web portal for people to configure settings for text messages, so we didn’t expect the load to be high.

After looking through the available options, we initially decided to go with www.hostingrails.com.

HostingRails Review

At the risk that some might not read this entire review, I’ll summarize our experience here:

Pros: Friendly, fast support.  Very Cheap.

Cons: Painfully poor server performance.  False advertising on website.  Bad upgrading support.  Outdated support articles.  Blacklisted IP’s for e-mail.

We initially went with Hosting Rails’ Shared hosting option.  For $8 we got 10 GB of space, 100 GB, and migraines.  The initial sign-up process was unexceptional, but things went downhill from there.  We naturally went to Google and searched for articles on deploying a Rails application onto hostingrails.com, and quickly found an article on hosting rails wiki “How to deploy a Rails application on HostingRails.com”.  Unfortunately this article which was the first hit on google is archaically out of date, and we wasted hours trying to get its procedure to work.  We created a support ticket for help with a step of this procedure, and this was our first experience with the knowledgable, fast, and friendly support.  We were quickly straightened out, and started working through the much easier and up to date process in the more hidden article on their wiki “How to deploy a Rails app with Passenger”.  

With this updated procedure in hand and the occasional promptly answered support ticket we soon had our application online (I should point out that this great support response was happening at 4 in the morning on a Saturday night!).  Unfortunately this accomplishment only led us to experience more issues.  It was quickly apparent that the performance of the server just wasn’t going to cut it.  At times the site was snappy, but at other times a page load could take upwards of 20 seconds.  As this is shared hosting some performance variance is to be expected, but this was well beyond acceptable.  

Continuing our deployment (with our fingers crossed that performance would improve once passenger got up to speed), we then worked on deploying e-mail.  I configured SPF and domain keys to try and ensure our outgoing e-mails wouldn’t end up in junk bins, but unfortunately despite both of these passing, our e-mail was still getting junked on gmail.  Having a bad feeling about this I performed a blacklist search on our IP address, and sure enough it was blacklisted.  We created a support ticket, but unfortunately received a very apathetic response:

We can request a removal from the blacklist, but due to compromised accounts and other customers sending spam, the blacklist is almost always reinstated shortly after having it removed.

Being the resourceful chaps we are, we moved our e-mail over to Google Apps, and kept on moving along.  Finally we had our application fully deployed, but had to come to the conclusion that the performance on the shared server wasn’t going to cut it, and that we’d need to move to a VPS to avoid being embarrassed at our site’s speed.  At this point we could have looked at other hosting options, but we had been very impressed with the support thus far and were convinced that VPS would solve our performance problems and we could move on.  

We were very optimistic about the migration to VPS, as hostingrails.com states on their site they are “experts in scaling Rails applications from shared to VPS and multi-server dedicated environments”.  They also state they provide a “Ruby on Rails Image Ready to Roll”, which had all the software we would need pre-installed.  Unfortunately both of these statements turned out to be false.  

After a painful account upgrade process with broken e-mail confirmation links and confusing billing we finally got a server online, only to find that it was a completely blank CentOS install with none of the functionality we had been told would be present.  At this point our shared hosting was already down, so we were understandably anxious to get our site back online.  We sent in another support ticket (about our 5th of the migration process) asking where the stated functionality was.  We patiently waited about an hour with no response, and found that our support request had been escalated to a level 2 request.  Deciding that no response would likely be forthcoming until morning we decided to call it a night.

In the morning we did in fact get a response, but it was not what we were hoping for.  

I apologize for the inconvenience, but the VPS Rails image that was used previously has become very out of date and is no longer offered the image that is currently on your VPS is the standard image all VPS accounts receive

At this point we had had enough.  We picked up our bags and decided to move elsewhere.  This time we did better research before choosing a host, and ended up at Slicehost.  I will do a follow-up post with a review of our experiences on Slicehost once we have been there longer, but so far the experience has been a dream relative to our nightmare with HostingRails.

 

[update] HostingRails.com has since removed the Ready to Roll image from their list of features; likely do to our experience.

Tagged , , , , , , , , , , ,

Ruby on Rails – Disabling a select tag using the select helper

There is a bit of a subtlety to this, and it took me a while to figure this out. If I used the select_tag helper I was able to disable the select menu, but using comparable code with the select helper it wouldn’t be disabled.

<% options= ['one', 'two', 'three', 'four'] %>
 
<%= select_tag :content, options_for_select(options), :disabled => true %><br />
<%= f.select :content, options, :disabled => true %>

Here my select_tag would be disabled like I wanted, but the f.select would not be. This made me quite perplexed, and with more research I discovered it’s because the “disabled” option for the select helper has been mapped to allow the developer to disable specific elements. For example, this code similarly yields differing behavior:

<% options= ['one', 'two', 'three', 'four'] %>
<% disabled_options= ['two', 'four'] %>
 
<%= select_tag :content, options_for_select(options), :disabled => disabled_options %><br />
<%= f.select :content, options, :disabled => disabled_options %>

In the case of the select_tag helper, the menu is still disabled as the disabled_options array will evaluate to true. For the select helper, however, the disabled_options array will tell the helper to set the options that match elements of the array to disabled. This is where I remained stuck for a while, not being able to figure out a way to use the select helper to disable the menu. Then looking more closely at the API documentation, I noticed a difference between the two helpers.

select_tag(name, option_tags = nil, options = {})

select(object, method, choices, options = {}, html_options = {})

The select helper has an additional set of parameters called “html_options” after the options. The select_tag helper conversely simply uses any parameters in its options array that don’t match expected options as html attributes. Based on this I wondered if I passed a hash array for the options parameter, if I could explicitly pass disabled as an html option, as follows:

<% options= ['one', 'two', 'three', 'four'] %>
 
<%= select_tag :content, options_for_select(options), :disabled =>true %><br />
<%= f.select :content, options, {}, :disabled => true %>

Sure enough this worked, and gave me the same behavior for both helpers! I was quite surprised to find such inconsistent behavior for these two helpers. It was reminiscent of my experiences with PHP and I’m disappointed to see it here in the Rails API. I would be curious to hear an explanation for why these two helpers are so different.

Happy Coding!

Tagged , , , , , , , , ,

Ruby on Rails – Nested Object Forms using a :belongs_to association

In a project I am currently working on, I have a one-way relationship using a belongs_to association.  I wanted to use the newer Nested Object Forms functionality added in Rails 2.3 to allow me to modify the properties of the related object in one form.

For the purposes of this post I’m going to use the following simplified code:

#address.rb
class Address < ActiveRecord::Base
  attr_accesible :address_string
end

#user.rb
class User < ActiveRecord::Base
  attr_accessible :name

  belongs_to :address
  accepts_nested_attributes_for :address
end

I ran into an issue when I was testing out this functionality in script/console and trying to assign attributes to the address through the user. I would encounter the error “WARNING: Can’t mass-assign these protected attributes: address_attributes” in my development.log. I proceeded to try and google a solution to this problem, and found many posts from users which encountered this issue, but none of them provided a solution. It appeared many people simply abandoned attempting to use nested attributes with a :belongs_to association. The solution to this problem is actually quite simple (once you know it!). Here’s the console log and the database log from my initial attempt:

#script/console
>> user = User.first=> #<User id: 1, name: "Bill", address_id: 1, created_at: "2010-08-20 21:49:52", updated_at: "2010-08-20 22:06:37">
>> params = {:address_attributes => {:address_string => "Up the tree", :id => 1}}
=> {:address_attributes=>{:address_string=>"Up the tree", :id=>1}}
>> user.update_attributes(params)=> true
>> user.address=> #<Address id: 1, address_string: "down the street", created_at: "2010-08-20 21:49:53", updated_at: "2010-08-20 21:49:53">


#development.log     
WARNING: Can't mass-assign these protected attributes: address_attributes

Note that the console even returns true from the operation, but the update address attributes aren’t assigned and the string is still “down the street” instead of “Up the tree” that we were trying to assign. The solution to this problem is to make sure that address attributes are added to the attr_accesible in the user model:

#user.rb
class User < ActiveRecord::Base
  attr_accessible :name, :address_attributes
  belongs_to :address
  accepts_nested_attributes_for :address
end

Now the error will no longer occur, and the address will be succesfully updated, as in the following console log.

#script/console
>> user = User.first=> #<User id: 1, name: "Bill", address_id: 1, created_at: "2010-08-20 21:49:52", updated_at: "2010-08-20 22:06:37">
>> params = {:address_attributes => {:address_string => "Up the tree", :id => 1}}
=> {:address_attributes=>{:address_string=>"Up the tree", :id=>1}}
>> user.update_attributes(params)                                               => true
>> user.address=> #<Address id: 1, address_string: "Up the tree", created_at: "2010-08-20 21:49:53", updated_at: "2010-08-20 22:41:46">

I hope this post can help save some time for others who run across this same issue.

Happy Coding!

Tagged , , , , , , ,

Ruby on Rails – Default Text Field Text That Clears On Click

I’m going to try using posterous’s code tags to make my first code post on this blog.  Bear with me if things don’t work out perfectly.

The designer on a project I’m working on (www.alertzy.com) wanted to have the effect where there is default text inside a text field, but it clears once the user clicks in the box.  The effect looks like this, before and after a user clicks on the text field (thanks to www.meshcanada.com for this example):

Beforeclick
Afterclick

As I am building this project in Ruby on Rails, I decided to write a simple helper to accomplish this behavior.  The helper itself is pretty straightforward, and I’ll leave dissecting the code as an exercise for you.  If you have any questions or suggestions for improvement feel free to post them in the comments.  Place this code in your application_helper.rb file in your Rails project.

  def default_text(text)
    onFocusFunction = "field = event.target || event.srcElement; if (field.value=='#{text}') {field.value = '';}else {return false}"
    onBlurFunction = "field = event.target || event.srcElement; if (field.value=='') {field.value = '#{text}';}else {return false}"
    {:value => text, :onfocus => onFocusFunction, :onblur => onBlurFunction}
  end

Then in your views you can simply call this helper function in the parameters of a field to add this behavior.  Here is an example for a text field for the users username which will display the text “Login” in the field.

<%= text_field_tag 'login', @login , default_text("Login")%>

The end effect of this will look like this:

Helperbeforeclick
Helperafterclick
Happy Coding!

Update August 20th/2010: It was brought to my attention that this helper wasn’t working in Internet Explorer.  This is because IE uses event.srcElement instead of event.target.  The code in this post has been updated to reflect this and should now work cross-browser.

Update August 28th/2010: I had forgotten that this functionality has been added to text fields in HTML 5 under the attribute “Placeholder”.  This technique is still useful for getting this functionality in non-HTML 5 compliant browsers.

Tagged , , , , ,

Hulu seems to be working in Canada

Yesterday I was experimenting around with different proxy software, which I use to allow me to watch Hulu in Canada despite their attempts to block it based on IP address.  I was very surprised to discover by accident that even without my proxy running, I was still able to connect to, and watch content from Hulu from my Canadian address.  I have had a few friends try this, with similar results.  I encourage everyone to go and give it a shot, because Hulu has some great content, and it would be great if we could get this content in Canada without having to jump through the hoops.

Update (August 7th 2010):  Unfortunately this window seems to have been closed.  Hulu cut me off about 2/3 through a program, and doesn’t seem to be allowing us to watch shows anymore (without going through hoops anyways).

Tagged , ,

Synergy – Great media center remote control software

I recently stumbled across a great solution to one of my problems in an open source project called Synergy.  The input device for my television which I use the most is a laptop which I have setup as a media server.  I use it to stream Pandora through my stereo, or to watch shows from Hulu.  Consequently I needed an effective means to control this computer without having to walk up to my laptop everytime I needed to fix something, or I wanted to skip a song on Pandora.  

My initial solution was to use an iPhone/iPod touch app called AirMouse.  I was very impressed with this application and found it to be far better than any of the other alternatives I had tried.  I still highly recommend this App, but unfortunately I found that the 5-10 second delay of taking out my iPhone, waking it up, and then waiting for AirMouse to connect to the server on my computer just became too much of a frustration.  

The next solution I tried was to use VNC to control my media center laptop from my MacBook which I almost always have on my lap when I'm in my living room anyways.  For those not familiar with VNC it's a technology used to remotely connect to and access computers.  I experimented with several different VNC configurations, but I always found them to be too heavy and sluggish, and they fell short of what I though the experience could and should be like.  Fortunately I stumpled across Synergy.

Synergy is probably not for those without some tech savvy, and this is probably it's biggest failing.  If you don't know what an IP address or Port are, then I'd recommend having your child, brother, sister, uncle, or whoever your family tech support is help you set it up.  It is worth the trouble.  What synergy allows me to do is to control my media center computer using the keyboard and touchpad of my MacBook.  Seamlessly.  The performance of the connection is so good that I feel like I am using a keyboard and mouse directly connected to my media center.  I can even play games on my media center using this control without any noticeable issues.  It also has some really cool features like the fact that the clipboard is shared between the two computers, so I can copy the URL from a browser on my MacBook, and paste it into an address bar on my media center.

You're probably wondering how much this magical software costs.  This is another one of it's great features.  It is both open source, and free.  I highly recommend giving this software a shot if you're like me and frequently use a media center on your TV, with another laptop either on your lap or nearby on a coffee table.  It may seem daunting at first to configure, but if there's sufficient interest I might write a tutorial on configuring it for this kind of use.  For those using a mac Synergy itself only has a command-line client, however there is a GUI version called SynergyOSX which provides a GUI interface.  I personally haven't used this interface so would be interested in hearing your experiences with it.

If anyone has found any alternative solutions to this type of problem let me know and I'll add them to this post!
Tagged , , , , , , ,

Watch Hulu Outside the US using Widecap

In my earlier posts on Pandora, I talk about setting up a proxy tunnel in order to be able to listen to Pandora even though you are outside the US.  Unfortunately, trying to use this same procedure to stream Hulu and watch your favorite TV shows doesn't work.  This is because the Flash plugin that is used to play videos by most site's doesn't use the proxy settings you have defined for your browser.  

One way around this is to use a "VPN" or "virtual private network" to similarly tunnel ALL the traffic from your computer through a server in the US, forcing even Flash to go through the tunnel.  I personally used this approach for a while, using a free tool called Anchor Free Hotspot Shield,  While this approach effectively worked, it always struck me as somewhat inelegant, and to the privacy concerned out there it can be concerning.  

That's why recently I was happy to stumble across a free program called Widecap.  Widecap allows you to configure applications to start in an encapsulated mode, allowing you to direct all traffic from the process into a tunnel as defined by you.  On my media PC I have it configured so that all my Firefox traffic travels through my proxy, and this forces even Flash to bounce through my server in the United States.  With this configuration I am able to take advantage of any of the US only services out there, including both Pandora and Hulu.  The unfortunate side of this solution is that it still requires you to have a proxy available in the US.

For more information on configuring a proxy, you can see my article on setting up Pandora.  If there is sufficient interest on this topic, I'll do a step-by-step how to on configuring Widecap.
Tagged , , ,

Scribd Does in Fact Support SSL!

I've been researching various document viewers for possible implementation on Firenest, and I was quite impressed with Scribd's iPaper interface.  Unfortunately I wasn't able to find any documentation on SSL implementation through their API, and had actually quite convinced myself that such support didn't exist.  Fortunately Jared at Scribd was able to correct me on this and point me to the following link, which I'm hoping to make easier for others who are in a similar situation to find:

I will likely be making a more detailed post about the various findings I've discovered researching and playing with the currently available embeddable document viewers I was able to find, so stay tuned for that.
Tagged , , ,

SkypeIn – Another service not available in Canada

Whatsmissing

I’ve once again been bitten by the lack of availability of a service in Canada.  I’ll be moving into a new apartment this April, and my new roommate and I were faced with the challenge of deciding what to do with the buzzer box for the apartment building.  We could choose one of our phones to forward it to, but this wouldn’t be ideal for obvious reasons.  I remembered looking at a problem like this when I was down in the US, and discovering that Skype had some features that might provide a good solution.  I started looking into it again, and sure enough with Skype you can set-up call forwarding to multiple numbers so that all the numbers will ring when a new call comes in, and then you can setup an online number, also known as “SkypeIn” to provide a local phone number that people can call, which will then get forwarded.  I started setting up and configuring a Skype account for this purpose, only to discover that online numbers aren’t available in Canada!  Reading in their forums this has been an issue for years, which is as yet unresolved between Skype and the CRTC.  

 
This is incredibly frustrating as its another example of a great service which is available in the US, but is somehow being blocked by the legislation in Canada, despite our supposed “Free Trade” agreements.  I’m going to look around and see if I can find a comparable service in Canada and will make a new post if I find someway to set this up here for a reasonable cost.  (If anyone has any suggestions please leave them in the comments!)
 
Ben

UPDATE: As pointed out in the comments there is a service which offers a skype-in number in Canada; http://www.skypeincanada.ca/.  I have not used this myself so I’d be interested in hearing on people’s luck using this service.  
Tagged

Part 3 of 3: Pandora in Canada – A step-by-step workaround

This is the last part of a three part post on Pandora in Canada.  The three parts were as follows:

  1. The History (or how we got to this sad state :( )
  2. Technical Background (or how Pandora blocks us)
  3. A step-by-step workaround (or a purely technical and not condoned by the author path to having Pandora work in Canada)

A step-by-step workaround

Disclaimer:  Attempting to circumvent the restrictions put in place to prevent Pandora from playing in your region may be a violation of your regional laws.  I don’t condone the use of this method, and this is rather a technical demonstration of the method currently used to filter regions.  Also depending on your web host, using this method may be a violation of your terms of service.


Step 1. Find a webhost

The first thing you need to find is a suitable web host.  Almost any old web host will do, but there are two crucial requirements.  They *must* be located in the US, and they *must* allow you to connect to their servers through something called “SSH”.  If you don’t know what that is don’t worry about it, but if there’s any doubt if a host you are considering will provide this ability, ask before you buy.  I personally am currently using Dreamhost.  As far as I know any hosts that will meet our requirements will be a pay service, but it is possible to find them for very cheap (Dreamhost, for example, occasionally has sales with very good prices).  If anyone finds a free offering that they’re able to get working let me know and I’ll add it to this post.

Step 2. Configure PuTTY

There is only one piece of software (in addition to a web browser) which you will need to setup your own personal proxy; an SSH client.  My personal preference is a free offering called “PuTTY”, which can be downloaded here.  For the purposes of this post my steps will assume that you are using PuTTY, though the explanation should be in principle transferable to other SSH clients if you have another preference.

To configure PuTTY, first open the application.  You should see a window that looks like screenshot below, though if this is your first experience with PuTTY you won’t have any “Saved Sessions” yet.

Puttyblank

Now we need to enter the information for the server that we will be connecting to for our proxy.  You will need to get this information from webhost; it will probably be listed as the SSH server.  If you can’t find this information, send an e-mail to your host asking the server hostname for SSH.  In my case as I’m using Dreamhost the host name is xxxxxx.dreamhost.com, where I have blanked out the subdomain for security reasons.  We’ll also want to put a name in the “Saved Sessions” box, though we won’t want to click the Save button yet as we have a few more things to configure first!  Your window should look like the screenshot below, with the hostname for your Host Name and you’re session name of choice instead of my information:

Puttypresets

Now we want to setup our username, so we won’t need to enter it manually each time we login to the server.  To do this we go the “Connection” menu in the “Category” window in PuTTY.  Click on the arrow beside “Connection”, and in the menu that expands click on the “Data” option.  Here we will want to fill in the “Auto-login username” field with the username for our webhost.  This is often the same username you use to login to their website, but if there is any doubt ask your webhost!  Fill your username into the field, and it should look like the screenshot below.  (as an FYI my username is not actually snuffles)

Autousername

Finally we need to actually configure something called our “Tunnel” which will allow our connection to act as a proxy.  Contrary to common sense we don’t go the “Proxy” options to configure this, but into the “SSH” submenu “Tunnels”.  Once in this window write “8080” in the “Source port” field, and change the radio option which is by default set to “Local” to “Dynamic”.  Your window should appear like the screenshot below.

Addtunnelbefore

Once this is completed, click the “Add” button.  After clicking this button, your window should look like this:

Addtunnelafter

Step 3. Connecting to the server

We’re done configuring PuTTY!  Not that tough was it?  At this point go back to the “Session” window and click the “Save” button.  This will save us from having to reconfigure PuTTY everytime we want to connect to our proxy.  Now we’re reading to connect to the server.  The easiest way to connect to the server in PuTTY is to double click on the sessions name in the “Saved Sessions” list.  Alternatively we can select the session, click the “Load” button on the right side, and then the “Open” button at the bottom of the screen.  Once you have completed these steps, a window that looks like a command prompt should open with a login prompt, similar to the one below.

Puttylogin

Here you need to enter the password for your webhost, and if everything has gone correctly you should see a message telling you you’re logged in.  This will differ depending on your webhost, but if you’re also using Dreamhost it should look similar to the own below.  If you either are not able to connect to the server, or are not able to login, make sure that everything is configured properly, and then contact your webhost’s support for help logging into their SSH server.

Puttyloginafter

Step 4. Configuring the web browser

If everything above has worked correctly, we’re almost ready to try connecting to Pandora.  The last step needed is to configure the web browser to use the proxy connection we have created.  For the purposes of this demo I’m going to assume you are using Firefox.  If there is sufficient demand for instructions for other web browsers I might add explanations for them in a later post.  In Firefox you need to go into the “Tools” menu, and click on “Options”.  You will then need to navigate to the “Advanced” section, and the “Network” tab.  It should look something like the screenshot below, depending on your version of Firefox.

Firefoxoptionsnetwork

Here we need to click on the “Settings…” button to get the proxy settings.  Once this window pops up you will need to change the Radio button from “No proxy” to “Manual proxy configuration”.  Lastly you need to fill in the “SOCKS Host” to “127.0.0.1”, and the “Port” field next to it to “8080”.  This should look like the screenshot below.

Firefoxoptionsconnectionsettin

At this point you can click the “OK” button and return to Firefox.  

Step 5. Connecting to Pandora’s Site

If everything has gone as planned, we are now ready to connect to Pandora’s website.  Go to your address bar and enter www.Pandora.com.  Remember that the legality of using this procedure will vary depending on  your region, and I don’t endorse using this method to use Pandora’s site where it’s use is restricted, but rather present this as a technical discussion.

Pandora