Saturday, October 17, 2009

LAPR - RoR on Hardy VM w/Postgres

Well, if there is LAMP, LAPP and LAMR. What about LAPR - Linux, Apache, PostgreSQL and Ruby on Rails? My friend Ben said he tried out Ruby (he's a Python guy), but it didn't support Postgres very well. I wanted to see for myself, (having just arrived from Missouri- the ShowMe state). First I tried installing Postgres on an existing RoR VMWare appliance, but for some reason, could not get Ruby talking to the gem.

Next I tried the opposite approach. Converting an existing LAPP iso into LAPR. I am more familiar with installing Rails on Ubuntu than installing PG. That went much smoother, after, of course gnashing my teeth on the previous install.

Turnkey[1] makes some nice appliances for testing things out and for deployments. They have a Rails stack, a LAMP and the aforementioned LAPP stack. (They also have a Django Python one I'm dying to try out). They are based on Ubuntu and seem somewhat affiliated with them. They seem to all use Hardy because that is the latest LTS release. There is also a way to deploy your app in the 'cloud". For some appliance vendors this means an Amazon EC2 instance. For Turnkey, they are using VPS.NET (see the site for details).

What I like about Turnkey appliances is they are distributed as (Live/Installable) .isos and not pre-built vdks or other VM images. They will work anywhere even burned to a CD and booted from there. They also offer a Core appliance where you can build your own and utilize the web based interface they've built.

Once installed or booted from the Live CD, you point your web browser at the provided IP address or SSH into it. (using the root password you set up during the install). From there you apt-get install away! Now, Turnkey keeps their appliances up-to date daily with security updates, but not with application updates. I had to apt-get update and then apt-get upgrade. On my LAPP instance, this seemed to update PostrgeSQL to 8.3.8.

As I am wont to do, I installed Ruby and Rails using the tried and true method outlined on the Download page for Rails [2]. This involves compiling from source. To do this on Ubunt, see my earlier Post: Ruby with readline on Ubuntu [3].

Once you have Rails installed, you need to install the sqlite3-ruby gem before testing it out, as Rails is configured to use Sqlite3 out of the box. But to install it, you have to first install Sqlite3 and its development library.
sudo apt-get install sqlite3 libsqlite3-dev
sudo gem install sqlite3-rub
At this point, create a Rails app and start the Webrick server. Point your browser at the ip address:3000 and you should see the familiar Rails Welcome page. Clicking on "About your application environment" should reveal all the various gem versions including the DB adapter:Sqlite3.

Next, set up a model using the scaffold generator:
./script/generate scaffold Post name:sting comment:text
rake db:migrate
Going to ip address:3000/posts should show the empty posts model you just created. Now, on to installing Postgres support:

sudo apt-get install libpq-dev
sudo gem install pg

The correct gem to install is 'pg', no matter what you may have heard. Next setup config/database.yml:
production:
adapter: postgresql
database: app
username: postgres
encoding: utf8
pool: 5
timeout: 5000
Turnkey LAPP ships with the postgres user having no password. Also, Postgres defaults to US-ASCII encoding, but Ruby expects UTF-8. (Ruby 1.9 lets you specify different encodings).

Finally, do another:
rake RAILS_ENV=production db:create db:migrate
# close and restart the server in production mode:
./script/server -e production
Now, enter any posts in your web browser, and they should show up in the phpPgAdmin screen.

You have successfully created a LAPR appliance. Go collect your fame and fortune!

[1] http://www.turnkeylinux.org/
[2] http://rubyonrails.org/download
[3] http://greenprogrammer.blogspot.com/2006/05/ruby-wreadline-on-ubuntu.html

Saturday, December 30, 2006

Saint Louis: The Pursuit of Rubyness ('06)

Well, this has certainly been a breakout year for Ruby in the St. Louis, Missouri area. Our little Ruby brigade (Stlruby.org[1]) saw its attendance mushroom from an average 7-8/meeting to around 20. So much so that we are seeking a larger space to hold meetings. We have been thankful to Mark Volkman and the staff at OCI [3] for sponsoring our group and providing a place to meet since our second meeting. Thanks Mark and everyone at OCI.

Curt Hibbs kicked off our first meeting at a dinner with Dave Thomas at the Gateway Software Symposium (the "No Fluff, Just Stuff tour,") in March of 2005. I wish I could have been there, but we reprised the dinner this year in March. We got to meet Dave, Bruce Tate, Justin Gehtland, Neil Ford and some other NFJS'ers. These guys are all very young, super brainy and quite funny. I had a blast at the dinner. Pics here[4]

Curt also presented this year at RailsConf in Chicago, a talk titled "Inside Instant Rails," about his ubiquitous InstantRails project for Windows. Curt hasn't sat on his laurels for both the InstantRails and One-Click Ruby projects for Windows. 2006 saw a new book co-authored by Bruce Tate and Curt: Up and Running Ruby on Rails. [5] He also contributed to Ajax Hacks by Bruce Perry [6]. His One-Click Ruby project hit 1 million downloads in November. It is always near the top of the most active projects on Rubyforge. Sliiiiiick!

Our numbers may have grown, but the reason might not be solely due to the explosion of interest in Rails. Occasionally, we've asked our membership what they are doing with Ruby and the answer seems more or less split 50-50 between Ruby and Rails work/interests. St. Louis has a fairly large number of web development organizations and a lot of enterprise shops in the biotech, aerospace and financial industries. Ruby is beginning to make inroads in Java shops and even a few Microsoft shops (of which there are a lot in this area.) Mark has even used Ruby at Scott Air Force Base.

Speaking of Mark and NFJS tour, Mark gave a presentation titled "Ruby Tools" this year. Mark's talks are always well done and very interesting even if you've never heard of the subject. I remember his Distributed Ruby presentation (when we could still all fit in OCI's conference room,) with great appreciation. I went home and built a Rails Wiki using no DB, just the DRb stuff. Mark will return with "Ruby Plays Well With Others" at the 2007 Gateway Software Symposium. The talk will cover JRuby and writing C extensions. A few people from our group attended the talk by Charles Nutter on JRuby at the Gateway Java group. Ruby and Java are certainly two great tastes that taste great together!

Mark and Rob Smith have taught various Ruby and Rails classes at OCI in 2006 with more to come in 2007. Ruby training has seen its biggest increase in 2006. The interest has led two of our members, Mike Sullivan and
Jeff Barczewski to form a new training consultancy (Inspired Horizons [7] specializing in Ruby and Rails training. It kicks off in 2007, registration is now open for the first workshops which will cover enterprise stuff with Rails and JRuby. (There is that Java thing again.)

Our membership sure gets around. In addition to Curt, Jeff, Mike and Kyle Cordes attended the RailsConf in Chicago. (I am counting Kyle as a member and sponsor at-large. He currently hosts our web site, and promotes Ruby in his Agile talks. Can't wait for your Lua Users Group to start up, Kyle!) Around town, Curt, Mark, Rob, Jeff and I have given talks to various other users groups. Besides Stlruby, we have presented at St. L Linux (stllug), StLUnix (sluug) St. Charles LUG (stclug) St. Louis Web Developer's (stlweb) and the St. Louis XP users group (xpstl) Several of them and other members also taught at the all day St. Louis Code Camp.[8] David Holsclaw gave a presentation on RoR and Jeff taught a class on Extending Rails featuring MasterView (more on that below.) Cory Foy (a member at-large in outstate Missouri,) taught a program on Ruby for C#/.Net developers comparing the languages and Rails and ASP.Net. I am sure there will be more of this in 2007. Stay tuned.

Speaking of Jeff, you may not be aware of his excellent Rails project MasterView MV is an attribute language for Rails. You can use WYSIWYG editors like DreamWeaver to edit your views as regular .html files and put attributes on tags like a, input and select. MasterView will render them as ERb in .rhtml files on the fly. 2006 saw the release of version 0.3 which featured a new DSL for writing your own customized attributes. Sweet!

Sean Carley has also been very active this year in Ruby projects. He contributed the cat2rb quiz to the weekly Ruby Quiz [9] He also founded the weekly hacking night in St. Louis. Attendance was low, so it is currently on hiatus. There are a lot of monthly IT related events in St. Louis, so much so that nearly every weeknight (and quite a few weekends as well) can entertain us. Balancing that with work and family can be quite tough. Sean has contributed to ruby projects like ParseTree, checkr, and Zentest. He has also been involved in many book and other writing projects. Be sure to check out his blog [10]

Quite a few of us are active in the blogosphere (oh how I loath that particular term. Forgive me.) Besides Sean's check out Curt's writing on O'Reilly's Ruby web log. [11] Curt also has his own Blog featuring a lot of Ruby wisdom [12] Also check out Pat Eyler's (a member on our mailing list, but lives in Utah,) blog [13] Pat also writes for the
O'Reilly Ruby blog. Kyle and Cory also have blogs. They are at [14,15] respectively Yippee for self-named blogs!

Some of our members have taken what they have learned and applied it to actual stuff.
Steve Molitor and John Hohlen have developed a fantasy golf site using Ruby on Rails. It is just getting off the ground, but they hope to grow the league this year. Check it out at [17]

What about yours truly? Well, I have given 4 presentations on Ruby and Rails at various users groups as I mentioned before. I am presently involved as a partner in a full time Rails consultancy (WDT Solutions [16]). We just finished a rather large Rails+Masterview commercial project for a company in the health care field. I contributed one bug to RSpec and a number of suggestions and feedback to Jeff and Deb on the Masterview team.

Our group has grown so much this past year, that we have decided to actually use a bit of organization. To that end we have formed a steering committee. We meet for about an hour at Friday's before the main meeting. Our first accomplishment is to lay out the presentations for the first few months of 2007. We also migrated the mailing list from Yahoo Groups to Google Groups, which has a much nicer management and user interface.

Well, I am sure I've missed something (or many somethings.) If I didn't cover your book, project, presentation in 2006, please email me and I'll incorporate it. That's it for ruby in St. Louis in 2006. 2007 is shaping up to be another fantastic year in the wide world of Ruby. Prognostication is not usually my forte, but if I had to guess at happenings in '07, I'd say that Curt will become even more famous. Dave and Bruce, et. al. will show up at the NFJS tour and have food with us. More projects will be contributed to, more blog posts written, more presentations will be given, more conferences will be attended. Outside of Japan, Seattle, Portland and Utah, St. Louis will be the place to be for all things Ruby.

Have a Happy New Year!

Ed
[1] StlRuby http://stlruby.org/ruwiki/ruwiki.cgi/
[2] New Google Groups for us: http://groups-beta.google.com/group/stlruby
[3] OCI http://www.ociweb.com/
[4] Pictures from our dinner with dave, Bruce and folks at the Gateway Software conference
http://www.cornetdesign.com/images/DSC00476.jpg (Dave is the one imbibing You can barely see the top of my head)
http://www.cornetdesign.com/images/DSC00477.jpg (Jeff is the one at the left closest to the camera.)
[5] Up and running Ruby on Rails http://www.amazon.com/Ruby-Rails-Running-Bruce-Tate/dp/0596101325/sr=1-1/qid=1167512231/ref=sr_1_1/103-6671475-6469421?ie=UTF8&s=books
[6] Ajax Hacks
http://www.amazon.com/Ajax-Hacks-Bruce-Perry/dp/0596101694/sr=8-1/qid=1167512145/ref=pd_bbs_sr_1/103-6671475-6469421?ie=UTF8&s=books
[7] Inspired Horizons, Ruby Training
http://inspiredhorizons.com/
[8] St. Louis Code Camp http://www.stlcodecamp.org
[9] cat2rfb http://rubyquiz.com/quiz77.html
[10] O'Reilly Ruby Weblog http://www.oreillynet.com/ruby/
[11] Curt's Comments http://curthibbs.wordpress.com/
[13] Pat Eyler : On Ruby http://on-ruby.blogspot.com/
[14]
Kyls's blog http://kylecordes.com/
[15] Cory's blog http://www.cornetdesign.com/
[16] WDT Solutions, LLC. http://www.wdtsolutions.com
[17] Fantasy Golf Site
http://www.rgfgc.com

Wednesday, August 23, 2006

Testing XML-ish stuff in Rails

Hi fellow Railsians,

Today post is in answer to a question from Chris T on the Rails list. Chris asks:
"Probably dead obvious, but are there any assertions for easing testing
of xml output, both for builder templates (for RSS feed -- something
like a version of assert_tag) and for the new restful stuff."

I've seen this question come up several times in the past. The trouble with assert_tag and assert_no_tag is that they are hooked directly to the response object of your controllers. Which means you can only use them in functional or integration tests. You could fake out a response object, but there is a simpler solution, just recreate them. They are essentially a call to the find method of HTML::Document.

Here is what I did: Add the following to the end your test/test_helper.rb:


# Add more helper methods to be used by all tests here...
def assert_xml_tag(xml, conditions)
doc = HTML::Document.new(xml)
assert doc.find(conditions),
"expected tag, but no tag found matching #{conditions.inspect} in:\n#{xml.inspect}"
end

def assert_no_xml_tag(xml, conditions)
doc = HTML::Document.new(xml)
assert !doc.find(conditions),
"expected no tag, but found tag matching #{conditions.inspect} in:\n#{xml.inspect}"
end




I chose to use the actual value as the first parameter rather than the expected value because it allows for nicer looking paramter hash values. To use it, use just like assert_tag and assert_no_tag:



def test_xml_correct
assert_xml_tag "", :tag => 'z',
:parent => {:tag => 'y',
:parent => {:tag => 'x'}}




I usually have a default object under test with a single method to output. This allows for a micro-DSL-ish thing to reduce typing overhead:




...
protected
def assert_render(conditions)
assert_xml_tag @thing.render, conditions
end

Tuesday, August 01, 2006

Simplified user roles in Rails

Usually, the discussion around user authentication and authorization in Rails revolves around an authentication plugin, engine or a login generator. Next, you might get into the types of users and this is where you might see a discussion about Roles, UserRoles and Users. There is plenty of tutorials about this usually describing an example of HABTM or has_many :through. But for simple cases, you can get the effect of user roles without much effort at all, just through normal Rails associations.

In addition to your 'users' table, create tables for each type of role. These can contain attributes specific to that type of user. For instance, you can have a admin type of user with specific flags allowing different types of CRUD access. A business contact user might have additional ways to be contacted (phone extension, cell phone, mail stop, etc.) For each table, add a user_id foreign key. In the models, make sure these all 'belongs_to :user'.

Then in the User model, add a 'has_one :admin' and 'has_one :business_contact' etc. for each associated table. The has_one association adds methods to the model to make it easy to query the relation:

user = User.find 1
if user.admin
# do admin stuff
end
...
details.save unless user.business_contact.nil?


Each user can participate in more than one role. This keeps the user login centralized and the authorization stuff very readable. Adding a new type only requires adding a new table and updating app/models/user.rb to add the has_one associtation.


This simple strategy might not be enough for your needs. It doesn't work if you anticipate adding user roles on the fly to a running system. In this case, you'd probably want to look into a permissions system tied to a HABTM based Role and UserRole model. I've only described a solution for a fixed amount of user types, more or less hard coded into the models.

Friday, July 07, 2006

Testing Helpers and Helping Testers

The Rails helper_test plugin [1] is a useful thing that provides you with more tools to better test-cover your code. View helpers that live in app/helpers should be tested in isolation from unit and functional/integration tests. This is true just on the face of it. But additionally, you get to access Rails helper methods which you are usually combining with your own stuff. Hard to do that in normal unit tests, and the setup in integration tests is a little too bloated for my taste.

There are a few tricks that can be used to make this run even smoother. The first trick is to utilize assert_tag to check your HTML generation. assert_tag wants to check the body in the @response object which is expected to be a valid XHTML string. But you are not in the request/response environment of functional/integration tests, so @response is not available. Not to worry, we can just fake it out for now. Create a class with an accessible instance variable that is an instantiated string named body:


class Response
attr_writer :body
def initialize
@body = ""
end

def body
"<x>" + @body + "</x>"
end
end

In your test method, assign @response = Response.new. Assign the output of your helper method to @response.body. Now assert_tag will work in all it's glory.

The next trick involves testing the image_tag helper. If my helper generates one or more img tags, they can be hard to test with assert_tag. The reason for this is due to the change in Rails to help the various asset tags work better with browser side caches. The helper
image_tag "graphic.gif"
results in something similar:
<img src="/images/graphic.gif?12345678">

where the parameter after the ? is a file based timestamp. This helps the browser to decide to get a new copy of the asset or not. But calling assert_tag :tag => 'img', :attributes => {:src => "/images/graphic.gif?12345678"} is brittle, since if you update the timestamp, (say the next time you get an update from Subversion,) your tests will break. The easy solution to this is to force the ASSET_ID to always be a fixed string. Add this line to config/environments/test.rb:

ENV['RAILS_ASSET_ID']=12345

Now this will be constant in your tests:


def test_image_asset
@response = Response.new
@response.body = my_helper_that_returns_an_img_tag
assert_tag :tag => "img", :attributes => {:src => "/images/graphic.gif?12345"}
end



[1] http://nubyonrails.topfunky.com/articles/2006/04/07/test-your-helpers

Wednesday, May 03, 2006

StL.rb Hacking Night - Hacking the Ruby Quiz

Well, once again Craig, Sean and I met this past Tuesday for the weekly hacking night of the St. Louis Ruby Brigrade. We decided to work on the current Ruby Quiz which Sean had submitted. It was a lot of fun and a good idea for what to work on if there is no other ideas.

This week's quiz [1] concerned cat2rfb.rb which from the RubyQuiz site he says : "The goal of cat2rafb is to implement a command line utility that will allow you to submit arbitrary text to http://rafb.net/paste/ and get the URL for the text back." You have to understand what rafb.net/paste is all about. This is a site where you can post snippets of code or text then it redirects you to a page where your code is displayed and syntax colorized. But the cool thing is the URL can be shared with others to collaborate.

From their FAQ [2]: "What is a 'nopaste' site?

A 'nopaste' site allows people to paste chunks of code for others to view. This is useful for situations such as asking for programming help on IRC, where it is frowned upon to paste chunks of code to the channel or to individual. With a nopaste site, the user pastes his or her code to the site and is given a url to provide to others so they can find the code."

What Sean wanted was an easy command line way to paste the code from files, or stdin w/o having to go through the web site. Bonus points if you convert the resulting URL from rafb.net through rubyurl.com which is a Rails equivalent to tinyurl.com that converts long URLs to short ones. (Not that the resulting rafb.net code display URLs are that long anyway.)

Sean hadn't actually come up with an answer for his own quiz yet, so that made me suspect he wanted to prime the WHN attendees with some actual cool work to do. In any case, it was a fairly good learning session for me. We actually set up an IRC session on freenode/#stl.rb to share links. Eating our own dogfood, I guess.

The basic idea is becoming familiar with Net::HTTP posts and gets. Sean went for a Ruby Golf approach, while I took the opposite approach. I wanted to provide options and error checking and read from an optional config file. The fields on the nopaste form allow you to choose from different languages, choose a nickname and give it a description. This makes it easier to find in the Recent pastes screen.

The other tricky part is understanding how to follow a redirect from Net::HTTP#post. Turns out Net::HTTPResponse has a bunch of subclasses. So you can do a 'case when' around the response object and then query its 'location' key (it behaves like a hash.)

I also figured out the issues wrt using GetoptLong and ARGF together. You need to process the arguments first, then set a post argument to ARGF.readlines. Also, RDoc::usage is a seriously cool thing. It looks at the comments at the top of your file and processes them into an usage statement and then exits. How can it see the comments in a file that calls it? Very deep Ruby-fu there. But this fits nicely with the DRY rule (comments and usage decared just once.)

So, we finished up right when the meeting was supposed to end. This kind of exploration to solve the quiz was well suited to the amount of time allocated for a hacking night. Look on ruby-talk for mine, Sean's and other answers to this week's quiz.

[1] http://www.rubyquiz.com/quiz77.html
[2] http://rafb.net/paste/faq.html

Monday, May 01, 2006

Ruby w/readline on Ubuntu

Getting Ruby running on Ubuntu 5.10 (Breezy) can be tricky. The issue is Breezy wants Ruby 1.8.3 from apt-get, and that has known problems with Rails 1.x. I usually recommend people install ruby 1.8.4 from source to work with Rails 1.1. But the base install of Ubuntu doesn't have many source build tools and libraries. This shows up in various places. For instance, running 'script/console' barfs complaining about missing the readline require. That is because irb wasn't built with it in the 1.8.4 build tree. Another issue you may have run into is support for rubygems is lacking due to a missing zlib development library. This may have messed up your install of Rails or various plugins.

Before we start read this guide: [1] Be sure to add the extra repositories, if you haven't yet.

Here are a bunch of commands that I executed to get Ruby built.


apt-get install build-essential
apt-get install bison byacc gperf
apt-get install zlib1g-dev
apt-get install libreadline5 libreadline5-dev
apt-get install libncurses5 libncurses5-dev temcap-compat
apt-get install libssl-dev


If you have previously tried to build it, then rm -rf ruby-1.8.4 and tar zxvf ruby-1.8.4.tar.gz; cd ruby-1.8.4; ./configure; make; sudo make install

Retest in your rails app: script/console. Everything should work.

The last install is for openssl development headers and libs. This is a Rake dependency in certain cases. (Not Rails specific.)

[1] http://ubuntuguide.org/