technology = evolution; open source = punctuated equilibrium
20
Nov
My eRubycon 2007 slides are on Slideshare. Service-Oriented Architecture with Ruby. Covers open-source libraries that make web services possible on Ruby.
21
Mar
After many months of working nights and weekends, Famiva is finally ready for public beta! So, what is Famiva anyway? It’s a free social network and collaboration service for families. Basically, it’s a web site that allows you build your family tree. Every relative you add will get the ability to complete their family tree by adding their relatives, and so on. Everyone works together and collaborates to build the “family network”.
Famiva is also a private portal. Features include photo sharing, comments, member profiles, family calendar, maps of photos and people, stories, events, reminders and more. The family network is tightly integrated with tools that let you share information with your extended family, keep track of who’s who and what’s going with everyone. For example, click on a member anywhere to see profile, their immediate family, the 3-level family tree or the entire family network. You can relate photos and stories to people, see them on the world map, etc.
I think Famiva demonstrates how Ruby on Rails can be used to develop complex web applications with non-trivial data structures (graphs) and Java integration. It also a nice use case for Ajax, Google Maps and Flickr integration.
To learn more about Famiva, check it out for yourself at http://famiva.com and visit the Famiva Blog.
11
Jan
Love Ubuntu and want to run a Rails server on Edgy Eft (Ubuntu 6.10)? Roll-up your sleeves for some "compiling from source" fun.
Please note that Ubuntu Fiesty Fawn has been released. It comes with Apache 2.2. If you can, avoid all this compiling and just sudo apt-get dist-upgrade!
Rails development on Ubuntu is a breeze, you can apt-get all the stuff you need. From Ruby 1.8.4 and MySQL driver to ImageMagick, the official repositories have got you covered. Deployment is another story. The bad news is that stuff that comes with Edgy just doesn't work, the good news, compiling stuff in Ubuntu, and Debian in general, is really easy.
Where's what we need to compile:
Because you can't do serious Rails deployment without a Mongrel cluster, and Mongrel needs a Load Balancing Proxy so that browsers can connect to the standard port 80. Ubuntu comes with Apache 2.0, which is no good because mod_proxy_balancer was not introduced until Apache 2.2. We need to grab Apache 2.2.x from the source and compile it ourselves.
Note: You _can_ use lighttpd but I wouldn't use it's mod_proxy plug-in. Why? Because it's load balancing bit is buggy and Zed says so. If you must use lighty, use Pound to do the load balancing (see below).
No point re-inventing the wheel, the good folks at Starman will show you how to build Apache 2.2. Don't have time to read? Simply get the latest Unix source from the Apache download site. Get some stuff from Ubuntu universe:
Remove existing Apache package, untar the Apache source and run:
Followed by
This will install Apache 2.2.3 in /usr/local, which is where I like it because it doesn't get confused with Ubuntu maintained stuff. You will have to point your /etc/init.d/apache to the new apachectl.
Pound is a decent standalone load balancer. You can learn more about using Pound with Mongrel here. One advantage here is that you can use lighttpd as a web server + proxy and let Pound do the balancing. It is quite configurable and comes standard with Ubuntu. Well, sort of. The Ubuntu Edgy package doesn't work very well. In my case, it kept crashing without any warnings. If you do want Pound, you will have to compile from source. Rob Orsini explains how to setup lighty, Pound and Mongrel here. Long story short, download Pound and untar (tar xfz) it.
Memcached is an in-memory cache that can help take the load off your database. I was attempting to use memcache as my Rails session store but the standard Edgy package refused to work for me. Rails would complain that my session was expiring within a few navigations. This would only occur under a Mongrel cluster; a single Mongrel or Webrick would have no problems. Strange.
So I got the latest memcached source and repeated the compile drill:
This fixed the problem but for some reason memcached would occasionally halt for several seconds, making my site slower rather than faster. I finally gave up on memcached and decided to settle for SqlSessionStore, which works like a champ! If any of you have insight or experience with this issue, please let me know.
All this compiling, albeit easy, should not be needed. The biggest downside of compiling is that you don't get to apt-get upgrade things. You could be missing out on a critical patch. If only the Ubuntu package maintainers would stay current, or someone (like you and me) would just take some time to build DEBs and publish a "Ubuntu on Rails" repository.
11
Jan
SD Times recently published my article on Tactical Business Applications with Ruby on Rails. It discusses the advantages of using Rails to fulfill enterprise business needs.
Get the full article here: SD Times - Rails for Tactical Business Applications
20
Nov
MySQL offers powerful out-of-the-box full text search capability. It allows you to do advanced search on text columns such as:
apple +computer -fruit
As of Rails 1.1.6, working with MySQL Full Text search is not that straight forward. The first problem is that Migrations doesn't support the SQL syntax for full text indexes. Your create table class has to to two things.
Here's a complete example:
That takes care of the Migration part. No big deal, you can't expect Migrations to support all the specific features of all database engines. The second problem has to do with Unit Testing. Rails schema dumper will fail to recognize the full text index and will try to generate a regular index. However, MySQL will not like creating an index on the TEXT data type, and your full text tests will fail as well.To resolve this problem, we will have to fixenhance the schema dumper located at ./active-record-1.*.*/lib/active_record/schema_dumper.rb under your Ruby gems or vendor (if you've frozen Rails) directory. The adapter can not tell us if we are using full text index, so we'll have to improvise and use a naming convention. Assuming all your full text indexes are prefixed with "FullText_", we can check for it and generate the appropriate schema.rb.
Here's the replacement code for the indexes method in schema_dumper.rb:
We check to make sure the database adapter is MySQL for good measure. That should do the trick. But wait! Don't modify the Rails code, use the plug-in instead! You can download the Rails 1.1.6 plug-in here. Drop it in your Rails vendor directory and enjoy full-text search with MySQL.
3
Jul
Problem: The Ruby on Rails plug-in installer's RecursiveHTTPFetcher makes certain assumptions about web servers that does not hold true from server to server. For example, it assumes:
RubyForge web server is an example of where these assupmtions don’t hold true. As a result, you can not simply copy your files to a web server and expect Rails HTTP plugin installer to just work.
Solution: Rails Plug-in Package Task
RailsPluginPackageTask is a Rake task designed to automate the publishing of Ruby on Rails plug-ins. It helps fill the gap by conforming to the Rails plug-in script's assumptions. Following the Rake package task conventions, it defines the "rails_plugin" task that recurses through your package_files, generates compliant index.html for each folder (that contains a file), and creates a directory structure that you can publish as a set for your plugin.
Example
The following example uses the Rake::RailsPluginPackageTask to create the package. It then uses the Rake::SshDirPublisher to publish the plugin directory to RubyForge.
You can download the ZIP package for this task and place it in your gems or project folder. For a complete working example, checkout ROXML from CVS.
Note: This release has only been tested on Linux. If it doesn't work on your OS, please let me know.
30
Jun
This page is shows information about projects that I am current working on outside of my day job as Senior Manager at BearingPoint.
Famiva - where families live online
Famiva is a private social network, genealogy and collaboration platform designed for families. Built on Ruby on Rails and Java, Famiva sports powerful yet easy-to-use features that allow families to connect, share photos and stories, keep up with events, etc. Famiva is a free service. Learn more by visiting Famiva.com or the Famiva Blog.
Enterprise Ruby
I am working on two Ruby projects aimed at improving enterprise support for Ruby, both targeted towards XML and web services.
RDIL
RDIL stands for Requirements Definition and Illustration Language. It is a domain-specific language for defining web application requirements using natural-language syntax. Using RDIL, you can define application structure, navigation, look and feel and layout, data types and other behavior using a simple RDIL source file. RDIL Generators are able to take this source file and generate HTML prototype, implementation specific code and other artifacts. Visit the RDIL RubyForge project page for downloads and more information.
ROXML
ROXML is a Ruby Objects to XML mapping library. With simple annotations, it allows Ruby objects to be marshalled back and forth from XML with custom mapping. This way, developers can create Ruby objects according to their Object Oriented design, and XML support without having to work with low-level Hash maps and XML elements. More information about ROXML can be found on the ROXML homepage and the project page.
Uddi4r
Uddi4r provides Universal Description, Discovery and Integration (UDDI) inquiry services for Ruby with the aim of supporting dynamic discovery in Service-Oriented Architectures. My goal with this project is make Ruby and especially Rails be first-class citizens in the SOA tools space. More information about Uddi4r can be found on the uddi4r project page. You can learn about uddi4r at the Enterprise Ruby Conference 2007 in Columbus Ohio.
16
Jun
Based on Ruby on Rails Philosophy and ActiveRecord Default Naming Standards
The goal of IT systems is to provide support the business objectives. IT departments have been guilty of focusing too much on their individual function, such as database administration or Java development, digressing into engineering perfect and losing focus of the bigger IT objectives. New conventions are emerging in the software development industry that are breaking old monolithic standards and promoting a more holistic view of the software development functions, with the goal of efficiently delivering business value.
Databases serve a specific purpose in the enterprise: to store and retrieve data so that user-facing services, such as application and business intelligence tools, can meet the business needs efficiently. In other words, if a database design reduces the development time for building a specific application or report while meeting the business objectives, than it should be designed as such, even if it doesn't follow old (and often unnecessary) conventions. Ruby on Rail's ActiveRecord framework supports such a convention; it promotes a common-sense approach to building databases that accelerate application and report development while meeting long-term business objectives.
Oracle identifiers (table/column names) are limited to 30 characters, which creates unwarranted tendency to abbreviate identifiers, and create artificial and often cryptic naming conventions. If you are concerned about Oracle's column name length, you'll be surprised how much you can fit into 30 characters by using good logical names. In many cases, a very long column name is a sign of normalization problem:
The objective of these conventionss is not to eliminate the need for translation of labels. These naming conventions will help you standardize around names that are logical, readable and consistent. Depending on your development environment, it may even help your tool translate your database objects names into your application or report development namespace.
A database row represents one instance of an entity, while a table is a collection of the same entities. Use plural nouns, e.g. PEOPLE, CONTRACTS, etc for database tables - this follows the common database convention. Use underscore to separate words, e.g. LINE_ITEMS. Do not abbreviate. Do not start table names with a number – this causes errors in certain application platforms. Do not use prefixes like REF_ or LU_ for reference tables, entity names should represent the information being stored, and not try to represent a usage scenario for the information.
Alternatively, you can use the singular form of entity names for tables, thereby following the Object Oriented Programming naming style and avoiding the need for translation from singular to plural and vice versa. ActiveRecord defaults to plural table names, this can be turned off as a global environment setting.
Recommended naming:
Not recommended:
For association tables (also known as intersection tables) that resolve many-to-many relationships, use the following naming convention: [name of first entity]_[name of second entity]. This may not always be possible, given Oracle's limitation. Use it whenever possible, it makes it easier to identify the physical translation of a logical relationship.
Recommended naming:
Not recommended:
Do not put application prefixes on table names for business data – this tightly couples business data to applications. Business data is a function of the business, not the application. There is always a logical name for business entities. Use schemas for the intended purpose of creating namespaces, to logically group relates entities and avoid naming conflicts.
Do not use a master schema that holds all tables, it is an anti-pattern and defeats the purpose of schemas.
Recommended naming:
Not recommended:
There are other obvious advantages of using schemas for logical grouping. For examples, schema level security policies simplify access control, storage settings can be defined at the schema level. In general, schemas and all objects within schema can be administered using schema-level operations.
Use a separate schema for development and testing, this way your test database can be wiped out or stages for automated unit tests and for testing reports. Use “_DEV” and “_TEST” suffix with the schema name to differentiate. Production schema name should match the logical name; it should not have a suffix.
Always use auto incremented numeric primary key. For consistency and simplicity, I recommend ‘ID'. It is a noun as defined in English language as a synonym to identity . Also, some frameworks, such as ActiveRecord, use ID as the default name for primary key.
Use auto increment (sequences) as a general rule, unless you want the application tier to manage the keys. Even the most obvious business keys can change, for example, DUNS number for identifying partners. If and when the business key changes, all the relationships will break. Business keys are pieces of business data that should have unique constraints.
Using numeric IDs makes database indexes more efficient. Strings, for instance, take more space to store than numbers. This space is saved in index storage, the space saving is propagated to all child tables' foreign keys.
Recommended naming:
Not recommended:
This convention is an extension of 2.1. Avoid concatenated keys at all costs. Concatenated keys complicate indexes and all DML statements. They take more space to store and index. The storage need and SQL complexity multiplies with every child table (the entire multi-column key has to be stored in every child table). Moreover, concatenated keys make object relational mapping complicated and error-prone. Follow this convention in conjunction with 2.1, use single integer primary keys – auto incremented whenever possible.
Recommended naming:
Not recommended:
This may sound like a violation of convention #2.2 and general principle of using logical names. The logic behind this convention is that all relationships can be named as one of the three types of associations:
If you use the above listed logical names for foreign key naming, the column name will not tell you which entity it is associating the entity with. This becomes a bigger problem when you have a child table with multiple parents, e.g. an order_items table could have a foreign key to an order and discount type.
ActiveRecord recommends using the following convention: [parent entity name]_ID. The advantage of using this convention is that you can tell the parent entity, direction and type of the association.
There is a downside to this naming convention; the column name does not tell you the nature of the association. For example, an employee can have two circular relationships, “reports to employee” and “mentored by employee.” In these kinds of scenarios, you can either extract the foreign key/keys into an association table, or use the following convention: [nature of association]_[name of parent entity]_ID.
I don't feel strongly about this convention, feel free to adopt any one standard and use it consistently; keep in mind that several Object Relational Mapping can infer the relationship if you follow the ActiveRecord convention of [parent entity name]_ID.
Recommended naming:
Not recommended:
Column names should be the logical name of the attribute. A good rule to follow is that the column name should be obvious to the end users; there should be no need to translate the name before it is presented in a report of application. This simple principal will not only add clarity to your database schemas, it will alleviate the need for maintaining application labels (unless your application supports multiple languages). You will also alleviate the need for meta-data for ad hoc reporting tools.
The remaining conventions are an extension and elaboration of this general principal.
Underscores serve as a friendly visual delimiter for words. Some databases allow spaces and mixed case in table names but most popular databases suppress this capability by default. For a standard approach that can be applied to all databases, use upper-case table names with underscores to separate words.
Frameworks like ActiveRecord can translate logical column names into object attributes and/or user interface labels using the following rules:
As an example, a column named “FIRST_NAME” will translate to “First Name” on the user interface.
Recommended naming:
Not recommended:
The table name specifies the context for the columns. Prefixing column names with table name is redundant. If you find a column name to be ambiguous without the table name, you may want to review your data model for normalization.
Recommended naming:
Not recommended:
Column data type is specified by the column definition in the table. Using type identifiers in the column name are redundant. If you are referring to a code, use convention 2.3. For date/time columns, ActiveRecord recommends using the logical proposition form.
Recommended naming:
Not recommended:
Do not use abbreviations that are not universal accepted. A good standard is to avoid all abbreviations except those that are defined in one of the official English Language Dictionaries. For example, abbreviations like SSN and ID are acceptable but DT, NUM and CD are not.
Recommended naming:
Not recommended:
16
Jun
I am happy to report back that I had no problems switching to MacOS as my development server. Moreover, MacOS interface felt just natural - as if I always knew how to use it. It could be because of all the things that Ubuntu and GNOME has taken from MacOS, like the preferences dialog, and privileged commands (sudo). I also felt readily productive in MacOS once I figured out how to launch the terminal. Bash and VIM, my two favorite console tools were already installed. Here is a report on the tools I configured to migrate from Ubuntu:
As of writing, Firefox official releases were only for PowerPC, which runs extremely slow emulated on the Intel platform. I had to get the bleeding edge build of Firefox Universal Binary. Fortunately, you can grab the official release now.
After googling around for a few hours and trying different RoR packagers, I found a nice, non-intrusive Mac Intel package at Todd Huss's blog. Unlike Locomotive, which is a PowerPC application that hides the underlying Rails infrastructure, Todd's package gives you a simple directory structure with Ruby and the basic gems that you can drop anywhere on your filesystem.
MySQL was a breeze. Just head on over to the official MySQL site and grab the Mac x86 version.
Okay, here's where it gets interesting: Before I can install RMagick (ImageMagick) and Subversion for Intel, I need to setup DarwinPorts so that I can compile my own binaries. For DarwinPorts, I need Xcode. So, I grabbed the latest Intel compatible Xcode from Apple's Developer Connection. Grabbed and installed Darwin Ports from here, and followed instructions on RubyForge to install ImageMagick and RMagick.
With DarwinPorts installed, installing subversion and lighttpd were a matter of single commands:
port install subversion port install lighttpd
I used svnadmin to create a new svn respository, copied my svn repository from Ubuntu, and voila! All my versioned files and change history is migrated. Don't you love it when software just works? Hope this post was helpful to anyone trying to setup an Intel Mac as a Rails development server.