Thursday, December 24, 2009
PuTTY with Ubuntu 9.10 and password less connections
"No supported authentication methods available"
The documentation on PuTTY wasn't helpful and after several searches turned up a lot of wrong answers I finally found a post that suggested that Ubuntu 9.10 uses OpenSSH which relies on OpenSSL and that something was wrong or incompatible with that OpenSSL and would cause PuTTY problems. (I can't find the post again to reference, sorry) I turned on logging in PuTTY to see what I could see and sure enough, OpenSSH is being used. I suppose there is a way to know that by looking on the server. Going with that assumption I decided to generate the keys on the server and then download the private key for use with PuTTY on my Windows box. Turns out that when I opened the id_rsa private key file with PuttyGen it was able to convert it to the "PuTTY" format for the file. Couple seconds later I loaded into PageAnt and viola I was connecting to my server via SSH without using a password.
Moral of this story. If you're using PuTTY to connect from Windows to an Ubuntu 9.10 server be sure to generate your keys on the server to save yourself some time and frustration.
References
Basic Security Settings (Linode Docs)
Linode VPS Hosting
Tuesday, December 22, 2009
Where to host my rails applications?
Here are the hosting choices I found that are available and "friendly" towards Rails application hosting.
- Sustainable Websites - I listed this ONLY because it's a "Green" hosting provider. I think it's cool that this hosting service powers it's servers off wind. Unfortunately, it doesn't give me enough control and feel a bit like the GoDaddy offering on the surface.
- Blue Box Group - Good virtual server choice here. The footprint I was looking at was $50 a month for 512MB RAM and 10GB disk space. This service has off-site remote backup included.
- slicehost - This one at first glance was in the right ball park. A virtual server for $38 a month that has 512MB RAM, 20GB storage, and 200GB bandwidth allowance. Automated backup service is available but costs extra.
- Rack Space Cloud - This is a pay by the hour service. The monthly cost was around $21.90 for the 512MB,20GB option but then I would need to add bandwidth charges. They have a calculator you can use to guess at your monthly cost. You'll need to know how much bandwidth you expect to use. Using the 200GB as a ceiling for the other plans I'm looking at this cost came out to around $58.90 a month.
- RailsPlayground.com - Again, another good option and the cost for the virtual server I think I need 512MB/20GB/200GB would be around $38.00 a month
- Linode.com - This provider doesn't offer a 256MB option. They start at 360MB as a minimum with 360MB/16GB/200GB for $20 a month. The 512MB/24GB/300GB option is $30 a month. They don't have a backup option yet but claim to be working on it.
- HostingRails.com - Not quite as easy to see what your cost per month will be on this site. If I understand the price matrix it looks like around $30 a month but bandwidth isn't as generous as the other providers. They do offer a pay as you go plan which could be a cheap way to go.
- heroku.com - One of the most interesting options. You should check this out just to see what's possible. If you need high availability in your solution then you might stop here if the cost doesn't scare you away. They have an intro level free option where you can try things out.
- Unfortunately, all of these seem to be good choices but obviously that will depend on your criteria. I was most concerned with balancing cost with performance. The first application I need to host will likely have low bandwidth requirements but I wanted hosting environment that would be easily expanded. I also am a bit of a control freak when it comes to putting my application and users at the mercy of automated and locked down "user friendly" hosting like GoDaddy and the like. (Notice that's not on the list above?) Here's my short list of criteria for a hosting solution:
- To bring the balance to the cost part of my equation I was looking for as close to a fixed cost as possible. Ideally as close to $20 - $25 a month as possible.
- I want SSH access with out of band console access too.
- Starting out Ideally I wanted 512MB of RAM with a reasonable amount of disk space. I have to have more than 256MB of RAM.
- A way to easily migrate/expand my hosting to have additional capacity. I care if it's easy but the solution doesn't have to be a click of a button.
- I wanted an easy way to perform backups.
- For me, this short list of criteria eliminated most of the list above on the first pass. If you're criteria is different then you will want to dig a bit into each of the options above because they all have something good to offer. I quickly narrowed the list down to three providers: slicehost.com, linode.com, and Rack Space Cloud.
- I connected with the FAQ and "Why Me" pages on both slicehost.com and linode.com. Found myself leaning towards those solutions almost immediately. The Rack Space Cloud option could actually be the cheapest starting point of all three but only if my bandwidth stays low. (And who wants or expects that?) Of the three I'm going to start with Linode.com and it's a good possibly I'll stay there until I have reason to move. They seem to be the middle of the road for me. They don't have the backup solution like slicehost.com but the ample disk space should allow me to manage that for a while. To top it off a recent performance benchmark has added some emphasis to my choice.
- I'd like to hear others experiences from using any hosting provider. Leave me a comment if you have something I should be considering with my choice.
Thursday, December 3, 2009
Rails Country and States Fields Made Easy
I've been writing Ruby code for just over a year now. It never ceases to amaze me how a fresh perspective can really put you on the right track sometimes. The Ruby programming language has been that kind of fresh perspective for me. Still, at times you have to tackle the same old problem once again. That's what happened to me when it came time to create the dreaded country and state combo box code once again. It seems I've written this code at least a dozen times in the last 24 years of creating applications. Sometimes it's been for client desktop applications and sometimes for web based but it is always the same and always boring. Not so this time! Even if I had to write it myself, which I started to do, it was going to be new because I'm still learning Rails and at this point loving it. Yes, I know, can you say MVC framework? I can but this one's in Ruby! What a difference. I'm off my soap box now.
If you need to a country and state solution for Rails and you've used Google to find some information and examples you know this topic has been beat to death. I almost gave up and started to have some fun writing it all myself. (You know, that dreaded pull the ISO table from somewhere online and create the SQL inserts followed by JavaScript and some…. (You get the picture). Then I stumbled across a Railscasts episode #88 and a GitHub project called Carmen and voila! My solution came together quickly. New and fresh yet still the same old thing.
Here's how you get this going.
First watch the Railscast episode #88. Way to go Ryan Bates! (RailsCasts has been a life saver this year.)
I decided to implement the dynamic JavaScript exactly like Ryan shows. However, I did have to change his JavaScript slightly for a number of reasons. These are my changes:
#dynamic_states.js.erb
var states = new Array(); <% for state in @states -%> states.push(new Array("<%= state[0] -%>", "<%=h state[1] -%>", "<%= state[2] -%>")); <% end -%> function countrySelected() { country_id = $('<%= @country_dom_id %>').getValue(); options = $('<%= @state_dom_id %>').options; indx = $('<%= @state_dom_id %>').selectedIndex; if (indx > 0 && indx < options.length) { curr_value = options[indx].value } else { curr_value = '' } options.length = 0; options[options.length] = new Option("Select a State","") states.each(function(state) { if (state[0] == country_id) { opt = new Option(state[1], state[2]); if (state[2] == curr_value) { opt.selected = true } options[options.length] = opt } }); if (options.length == 1) { $('<%= @state_parent_dom_id %>').hide(); } else { $('<%= @state_parent_dom_id %>').show(); } } document.observe('dom:loaded', function() { countrySelected(); $('<%= @country_dom_id %>').observe('change', countrySelected); });
I needed to change the code that pushes the values on the states[] array. My values are coming from an array and they'll be string data as you'll see from the Carmen project later on.
I also needed to fix it so that if I supplied a selected value for the State list it wouldn't get stepped on by the JavaScript immediately calling the countrySelected()method. This was something Ryan added after the episode was produced (see his show notes) which sets up the fields properly the first time.
And last, I needed to supply DOM ids for my fields and because I have two models that have state and country values. I know this is not very DRY but it is what I have for now and I'm certain to re-factor it soon.
Next, take a trip over to the Carmen project on GitHub (thanks Jim, next time I'm in Chicago I owe you a beer) for a simple file system based approach to the Country and State data you'll need. It's actually nice not having to maintain the DB tables for this again. I might re-think that later but for the project I'm on right now this is just perfect. I stuck this in my vendor/plugins folder for the project I'm working on and then changed my view and the Javascripts_Controller class. Here's the code:
#Javascripts_Controller.rb
class JavascriptsController < ApplicationController def dynamic_states_for_user @states = getStatesArray @country_dom_id = 'user_country' @state_dom_id = 'user_state' @state_parent_dom_id = 'state_field' render :action => 'dynamic_states' end def dynamic_states_for_contact @states = getStatesArray @country_dom_id = 'contact_country' @state_dom_id = 'contact_state' @state_parent_dom_id = 'state_field' render :action => 'dynamic_states' end private def getStatesArray @states = Array.new Carmen::STATES.each do |country| id = country[0] list = country[1] list.each do |state| @states.push([id, state[0], state[1]]) end end return @states end endI simply built an array for the @states variable from the Carmen::STATES data. I could have probably adjusted the view to loop through this data directly or maybe even changed the JavaScript but as you can see, I didn't.
Now for the final steps, all you need to do is adjust your views to contain the handy dandy Carmen view helper methods and you're done.
#new.html.erb
<% javascript 'dynamic_states_for_user' %> <% form_for @user, :url=> { :action => "create"} do |f| %> <%= f.error_messages %> <%= render :partial => "form", :object => f %> <div><br/><%= check_box_tag("send_reg_email","true") %><%= label_tag('send_reg_email','Send welcome registration email to user?')%></div> <div><br/><%= f.submit "Save" %> <%= submit_tag 'Cancel', {:confirm => 'Cancel changes?', :name => 'cancel'} %></div> <% end %>
#_form.erb (my users record partial)
<tr> <td><%= human_label User, :country %>: </td> <td><%= country_select(:user, :country, nil, {:prompt => "Select a Country"})%></td> </tr> <tr id="state_field"> <td><%= human_label User, :state %>: </td> <% if @user.country && Carmen::states?(@user.country) -%> <td><%= state_select(:user, :state, @user.country, {:prompt => "Select a State"}, { :style => "width: 230px;"}) -%></td> <% else -%> <td><%= select( :user, :state, options_for_select([],""), {:prompt => "Select a State"}, { :style => "width: 230px;"})-%></td> <% end -%> </tr> <tr> <td><%= human_label User, :zipcode %>: </td> <td><%= form.text_field :zipcode, :size => 15 %></td> </tr>
That's all it takes to get the dynamic client side JavaScript implementation of Country and State paired select fields. Enjoy!
References
Wednesday, December 2, 2009
Issue under Rails formatting date time values
I think Rails has a very nice way of handling the format of dates and times in the views. You can substitute your own formats when the default one used by rails doesn't meet your needs. There are numerous postings on how to do this and I've referenced a few at the bottom of this article. Read one of those articles if you need to find out how to do this. I'm going to cut right to the reason for this post. I had setup my own date format as such:
Time::DATE_FORMATS[:for_column] = "%b %d %Y (%I:%M %p)"
Then in my view I was using it like this:
<td style="text-align: center"><%= user.last_login_at.to_s(:for_column) -%></td>
Naturally I was doing this in several views and unfortunately some were working and some were not. I was on occasion getting the error:
"wrong number of arguments (1 for 0)"
on the call to user.last_login_at.to_s(:for_column)
Since I had a few working examples I spent quite a bit a time comparing the working examples with the failing ones. I found old posts on issues with concerning this topic and apparently there have been several issues with date time formatting under rails (no surprise here) and unfortunately a few of the posts sent me down the wrong path. After about an hour of wasted time I discovered the ticket #1701 on Lighthouse which shed some light on the subject. It turns out that the alias for to_s is not setup properly when the datetime field is nil. That means the to_s method of the nil object is being called and it doesn't have any arguments.
My work around for this situation was to create a helper method. Hopefully you find this post useful and it saves you the hour I lost.
def fixDateTimeFormatting( field )
if(field)
field.to_s(:for_column)
else
field.to_s
end
end
References
NOTE: These are fairly old posts and contain information that is useful but not necessarily accurate for Rails 2.0+ so keep that in mind while reading.
practical ecommerce – Custom Date Output Using Rails