Rfm: The FileMaker API for Ruby
This page is also available in Japanese (courtesy of www.famlog.jp)
Rfm brings your FileMaker data to Ruby with elegance and speed. Now your Ruby scripts and Rails applications can talk directly to your FileMaker server with a syntax that just feels right.
A Better Way to Code
There is no better language than Ruby for clean, expressive, powerful code. Ruby’s 100% object oriented structure and elegant language constructs help make you a more efficient developer. We’re huge Ruby fans, and it shows in the design of Rfm. It seamlessly merges FileMaker concepts and Ruby idioms so things just work the way you’d expect. Click Why Ruby? above for a few shining examples.
Why Ruby?
There are a lot of reasons to use Ruby. Many people swear it’s the easiest, prettiest, and most expressive language around. And because Rfm is fully object oriented, it fits right into your existing Ruby code perfectly.
Riding the rails
Let’s be honest. The biggest reason most people consider Ruby is because they want to use Ruby on Rails. Rails is a web framework that helps streamline the process of building web sites, web applications, and web services. Although it is a relative newcomer compared to web stalwarts like PHP, ASP, .NET, and JEE, Rails has become extremely popular. And the reason is simple: It makes building web sites easier. Now, with Rfm, this industry-leading web technology is available to FileMaker Pro users.
See the Examples section to download a real, fully functional web site built with Ruby on Rails and Rfm.
Express yourself
When people talk about Ruby, inevitably the word expressive comes out. What does this mean? Simple: in Ruby, you can express complex ideas easily, with simple code. Once you get the hang of it, you’ll be astonished how much you can accomplish without a lot of code.
Here’s a very simple example. Suppose you have a customer in mind, and you’d like to know how much he’s spent at your store. Here’s how you would find the total value of all orders in Ruby:
total = 0.0 db["Order Layout"].find("Customer ID" => 1).each {|r| total += r["Total"]}
That may look a little complex at first, but once you know Ruby’s basics, it is really quite readable. In english, it says “On the layout called Order Layout, find every record with ‘1’ in the Customer ID field. Loop through each of them, and add each Total field to my variable.”
And now, the equivalent code in PHP:
$total = 0.0 $cmd =& $connection->newFindCommand('Order Layout'); $cmd->addFindCriterion('Customer ID', 1); $result = $cmd->execute(); foreach($result->getRecords() as $record) { $total = $total + $record->getField("Total"); }
The PHP code isn’t bad per se, it’s just more to remember, more to type, more to read through…more fuss. You could say it takes less work to express the same idea in Ruby.
Errors that make themselves known
Ruby’s expressiveness shows up when it comes time to tackle errors too. Inevitably things go wrong, and your code should probably handle common problems reasonably well. For example, what happens if there are no order records for the customer in the example above? In PHP, you’ll get an ugly error message on the page (something about objects and methods and types). To properly handle this error possibility, you need to revise your PHP code:
$total = 0.0 $cmd =& $connection->newFindCommand('Order Layout'); $cmd->addFindCriterion('Customer ID', 1); $result = $cmd->execute(); if (!FileMaker::isError($result)) { foreach($result->getRecords() as $record) { $total = $total + $record->getField("Total"); } }
This version checks to make sure PHP didn’t run in to an error of some kind when executing the find action. How do you revise the Rfm example to handle the no-records-found problem? It already does. In Rfm, no records found isn’t an error. It just means you get an empty set of records back. Since Ruby is happy to loop through an empty array (it simply doesn’t enter the loop), your total will calculate without trouble. (If you want Rfm to raise an error when no records are found, you can tell it to. But usually you don’t want it to.)
Other problems could happen though. Maybe your Web Publishing Engine isn’t running, or the database is not open. If an error like this happens, Rfm raises an error in Ruby. This will instantly abort processing of the script and report an error on the web page or console. Since errors are automatically detected, you don’t have to check for them maniacally every step of the way through your code. If you need to detect an error and do something (like show a nice message), you can do it easily:
total = 0.0 begin db["Order Layout"].find("Customer ID" => 1).each {|r| total += r["Total"]} rescue Rfm::Error::RfmError puts "I wasn't able to talk to FileMaker!" end
The rescue
command in Ruby lets you plug in some code that automatically kicks in whenever an error is encountered in the block of code above it. This way you can be as fine grained or as nonchalant as you want to be, and still be confident a stray error won’t leave your script doing things it shouldn’t.
Object oriented goodness
Unlike many other scripting languages, which have a little objectishness rolled in, Ruby is object oriented at its core. That’s why Rfm is able to provide an interface that feelslike real Ruby. For example, when you perform a find with Rfm, you get back a ResultSet
object, which is essentially a group of records. Although FileMaker has some pretty specific capabilities this object needs to support (like field metadata, and portals), a ResultSet
has a lot in common with a simple Ruby Array as well. Thanks to the power of object programming, a ResultSet
is an Array. So if you’re familiar with Ruby (and you will be soon), Rfm result sets work just like you’d expect. You can loop through them, count them, combine them, and otherwise work with them just like any other array.
By contrast, with a non-object-oriented language like PHP, sets of records have to be handled in a special way since there’s no way to augment the built in array. That means you have to learn two ways to loop: one for arrays, and another for FileMaker records.
Examples
Rfm can be used for everything from highly interactive web sites to behind-the-scenes processing scripts. Here, you can see a few simple examples.
The Rfm Sample Site
The best way to see Rfm in action is to check out the sample site. This simple web site was built in Ruby on Rails and Rfm. Best of all, you can download the complete source and run the sample site on your own computer (you need to install Rails first). It uses the Server Sample database that was automatically installed on your FileMaker Server, so you can just point it at your server and watch it work.
open site now
-or-
Download the code
Other Examples and Documentation
The documentation included with Rfm is loaded with additional code samples to help you on your way. You can see the docs online right now.
Get Started
To take advantage of Rfm in your own work, you need a few things. First, you need a supported version of FileMaker Server (see below). You also need Ruby, Rfm, and (optionally) Ruby on Rails. This page tells you everything you need to know to start producing gorgeous code.
Get a supported FileMaker Server product
Rfm uses FileMaker Server’s XML API, so you absolutely, positively need a FileMaker Server. Luckily, with the recent release of FileMaker Server 9, this just got a lot cheaper. Specifically, you need:
- FileMaker Server 9.0 or later
- or FileMaker Server Advanced 7.0 or later
In either case, you’ll need to install both the FileMaker Server software itself and the Web Publishing Engine. Consult your FileMaker Server documentation for complete setup instructions.
Get Ruby, Rails, and Rfm
Installing Ruby, Rails, and Rfm is a breeze. Note: If you already use Ruby on Rails, skip straight to step 4.
- Ruby 1.8.4 or later
If you have Mac OS X 10.4.6 or later, you already have the right version of Ruby. If you use an older version of Mac OS X, today’s a great day toupgrade. Windows users should get the One Click Ruby Installer. - Ruby Gems
Ruby on Rails, Rfm, and thousands of other awesome Ruby extensions are available through the Ruby Gems system. It makes installing these packages a breeze. Unfortunately, you have to install Ruby Gems itself first. First, download the the latest version of Ruby Gems. Unzip the package, and runruby setup.rb
from the command line. On Mac OS X, you probably need to saysudo ruby setup.rb
instead. This script will install everything Gems needs. - Ruby on Rails
Once Ruby Gems is installed, installing Ruby on Rails is a snap. Just entergem install -y rails
on the command line. (Again, Mac users will want to addsudo
to the beginning of the command.) Ruby Gems goes to work finding Rails and everything it needs. It will ask you for confirmation once it’s picked the packages. Just typeY
and press enter or return. (Note: If you are just writing ruby scripts, and not building web sites, you can still use Rfm, but you don’t need to install Rails. Just skip to the next step.) - Rfm
Last step: use Ruby Gems to install Rfm. This time the command is (you guessed it)gem install rfm
. (It probably goes without saying at this point, but fellow Mac mavens, please usesudo
.) After a few seconds, you’ll have Rfm tucked neatly away and ready to use in any Ruby script.
Get the samples
The easiest way to get started with Rfm is to download the samples. This package includes a sample Ruby on Rails web site (you can see it live here) and an example Ruby script.
Read the docs and get the samples
Rfm includes comprehensive documentation, which you can get from your Gems documentation server, or from right here.
Also, click the Examples section above to download a working Rfm/Ruby on Rails sample site.
Frequently Asked Questions
Still have questions? Hopefully they’re answered here, but if not, feel free to contact us.
Should I use Ruby on Rails for my FileMaker web publishing?
Yes, absolutely.
How much does Rfm cost?
Zilch.
Is it really free? What if I want to use it for commercial purposes? What if I want to include it with my selling product?
Yes. Honestly. Rfm is licensed under an MIT license. This is an astonishingly open license. You can use it for free, and distribute it freely with your own creations. You can modify it, and build your own products around it. You can even make your own Rfm (with a different name) and release it as a competitor to Rfm. The only requirement is that the copyright notice from the License file be included someplace reasonable in anything you ship.
I’ve heard Ruby is slow. Will my site be a dog?
Honestly, Ruby is slower than some popular scripting languages, including PHP and Perl. Ruby’s focus is not raw speed. Rather, it’s all about developer productivity. This should be a familiar concept to anyone interested in Rfm: It’s just like FileMaker.
Even though there are faster database servers out there, none of them offers the ease of use and productivity of FileMaker Pro. FileMaker and Ruby both get it: For the vast majority of applications, speed is not the limiting factor. Database and HTTP overhead generally account for much more of your web response time than code processing, and Ruby executes plenty fast for all but the most extreme edge cases. Besides, compare the cost of a slightly faster server to the cost of software development. A happy, productive developer is worth a dozen cheap boxes.
How have I gone all my life without such an awesome web platform?
The world will never know.
Do I really need FileMaker Server? I don’t have a lot of users and I’d like to point my Ruby scripts at a copy of FileMaker Pro
No can do. Rfm uses FileMaker’s RESTful XML API, which is only available with FileMaker Server.
Is Rfm an ActiveRecord driver?
Nope. It’s a totally different beast, but it’s easy and elegant to use.
Why not?
Rfm creator Geoff Coffey decided early on that wedging FileMaker into ActiveRecord would be a nuisance. Some of the reasons, in no particular order:
- FileMaker’s ODBC support is a little spotty and the ActiveRecord ODBC driver doesn’t work with it. It sure feels like a lot of work to change that.
- FileMaker is awesome, but it isn’t a traditional SQL database. Although one could mimic FileMaker concepts in an ActiveRecord-like way, it wouldn’t feel like FileMaker anymore. But it would still be FileMaker on the back side. This means ActiveRecord experts would find FileMaker annoying since it isn’t “standard.” And FileMaker experts would find Rfm annoying because it isn’t “standard.” We didn’t want to annoy anybody.
- FileMaker’s XML API is a lot more mature, heavily used, and trustworthy than ODBC on FileMaker, so it seemed like the right way to go.
- It would required copious witchcraft to make ActiveRecord work through the XML API. Maybe after Harry Potter comes out…
On the bright side, if you disagree with all of the above and think we’re flat out wrongyou’re free to use Rfm to help you build ActiveRecord support. If it works well, we might even roll it into Rfm proper some day.
When I try to start up my Rails web site, it complains about database configuration. Must I have an empty SQL database? I just want to use FileMaker.
When you’re using a SQL database, Rails uses the (awesome but FileMaker-uncompatible) ActiveRecord. It tries to connect to a SQL database whenever you launch a Rails app.
The solutions is simply to turn ActiveRecord off. Look in your environment.rb
file for a section like this:
# Skip frameworks you're not going to use (only works if using vendor/rails) # config.frameworks -= [ :action_web_service, :action_mailer ]
The config.frameworks
setting lets you tell Rails which parts you don’t need. Just uncomment it and turn off ActiveRecord:
# Skip frameworks you're not going to use (only works if using vendor/rails) config.frameworks -= [ :active_record ]
Your app will now start without complaint.
I think I’ve set everything up correctly, but I keep getting an “authentication error.” It says my FileMaker account name or password is wrong. What gives?
The account (or accounts) Rfm uses to log in to FileMaker must have the “Access via XML Web Publishing (fmxml)” extended privilege. In FileMaker, choose File -> Manage -> Accounts & Priviliges (or File -> Define -> Accounts & Privileges if you have an older version of FileMaker).
Switch to the Privilege Sets tab and open the privilege set your Rfm account is assigned to. In the bottom-left corner of the Edit Privilege Set window, turn on the “Access via XML Web Publishing” extended privilege. Dismiss all the open dialog boxes and try again.
Rfm should be much happier now.
What’s next for Rfm?
As an open source project, Rfm is open to input (and even code contributions) from all its users. We’re discussing future features all the time. Some ideas on the table:
- One-line container download support:
image_data = myRecord["Photo"].download
ormyRecord["Photo"].download("file.jpg")
- File upload support into container fields (is this even possible with FileMaker? Not sure.)
- Additional options for easily running scripts.
- Rails enhancements: direct database.yml support, centralized configuration and automatic database and layout object instantiation. Anything else we can think of to keep Rfm DRY.
- The awesome idea you’re about to send us.