Topic “Ruby on Rails”

OpenSourcery Developing Healthcare IT Standards for CCHIT

logoCCHIT.gifOpenSourcery has partnered with CCHIT to build the next generation of tools for verifying healthcare IT standards. The web-based application, written in jRuby on Rails, moves certification away from a manual process to an automated, easy-to-use web interface. The project joins OpenSourcery and collaborators MITRE and CitiusTech with the Certification Commission for Healthcare Information Technology, better known as CCHIT. CCHIT is a recognized certification body (CRB) for electronic health records, and is a widely respected, independent nonprofit organization.

CCHIT selected OpenSourcery to work on Laika -- the aforementioned certification project -- because they were impressed by our Ruby on Rails expertise and the open source electronic medical records (EMR) application we've developed, elementalClinic. We're honored to be the sole paid developer on this exciting project.

Among the technical goals for Laika:

  • Migrate the Ruby on Rails application to work in jRuby, which will
    ease deployment and integration with Java-based testing tools.
  • Create a plug-in system that will make it easy for developers to add
    new health care validation standards in the future.
  • Improve stability of the core application.

Laika is currently part of the certification process for the C32 standard, with Patient Identifier Cross Referencing (PIX), Patient Demographics Query (PDX), and Cross Enterprise Document Sharing (XDS) certification as near-term project goals.

Software engineer Alex Kroman has assumed a leadership role in CCHIT's Laika project, working as the Project Manager and lead User Interface designer. Fellow OpenSourcery software engineer Zack Hobson is the lead jRuby on Rails developer for the project. While Alex and Zack are the principle actors, a variety of OpenSourcery employees have been integral in the project's success.

Please visit elementalClinic to learn more about OpenSourcery's experience with healthcare IT, and subscribe to our RSS feeds to stay apprised of our work with CCHIT and others.

Tagged as: Custom Development, elementalClinic, Health IT, Ruby on Rails

Beware of Top Level Methods in Ruby [updated]

In a Rails project we're currently developing, I ran into an odd failure while running rake:

$ rake gems:unpack
(in /home/hobson/railsproject)
rake aborted!
undefined method `[]' for :sourdough:Symbol
/home/hobson/railsproject/lib/tasks/import.rake:113:in `method_missing'
...

Why does this trace end in a totally unrelated rakefile? A look at the source of this file provided a simple explanation: in order to break up the logic of a complicated Rake task, someone had defined a large number of constants and utility methods (including method_missing!) without a surrounding class or module namespace. Other Rake tasks were accidentally triggering this method_missing implementation because it was defined at the top level. This is why it's never a good idea to define methods in the top level of any Ruby file that might be included as part of a larger system. The solution is to wrap the methods in a module, and include that module in the task namespace:

module ImportUtil
  # you can define any method you want here, including method_missing.
end
 
namespace :import do
 
  include ImportUtil
 
  task :something do
    # you can now call everything defined in ImportUtil as a top level method
  end
end

This avoids poisoning the top level of your Ruby environment with Rake utility methods. The lesson here is that since Ruby makes it so easy to include modules at any level, it's almost never necessary to define a method at the top level. Especially not method_missing.

UPDATE: Whoops, it turns out the solution I proposed above does not work. Since rake "namespaces" are really just blocks executed at the same level at which they're declared, the module include causes the methods to be included into the top level anyway. While the final lesson of this post remains true, the only solution I'd recommend (and the one we eventually took with the code above) is to remove the offending code completely, and don't ever define method_missing (or any other method, if you can help it) at the top level.

Tagged as: Rake, Ruby, Ruby on Rails

Fixture Replacements Are Catching On

Ruby on Rails is well known in its capacity as opinionated software, but there are a couple of things on which Rails and I never agreed. First among these is test fixtures, a feature that I learned to loathe immediately after I recognized the alternatives. My favored approach for creating test data is to generate it at testing time using a factory API, an idea I first saw described by Dan Manges a few years back. This idea has since then caught on, and now there are many implementations of what are most commonly termed fixture replacements.

The problems with fixtures are now fairly widely understood: they are difficult to maintain, they separate your test data from your tests, and they can increase the brittleness of your test suite. At the time, however, this idea hadn't caught on widely. Without many alternatives that met our needs, and inspired by Dan's post, Justin Balthrop and I collaborated on a package that directly implemented Dan's proposed API, called ModelFactory. Since then I've used this tool in a handful of projects as a replacement for fixtures, and Justin and I have expanded the functionality of ModelFactory as needs have arisen.

The purpose of ModelFactory is to generate valid ActiveRecord objects that can be used instead of fixture-generated objects. ModelFactory allows you to clearly demonstrate your intent because you only specify attribute values that you care about, while everything else is valid but essentially (and intentionally) opaque. Here's an example usage of the original ModelFactory API:

require 'model_factory'
module Factory
  extend ModelFactory
  default User, {
    :name => 'Factory User',
    :login => 'factoryuser',
    :email  => 'factoryuser@example.com',
    :active => true
  }
end
 
class SomeTest < Test::Unit::TestCase
  def test_inactive_user
    assert !Factory.create_user(:active => false).active?
  end
end

Occasionally I'd check to see what new alternatives had become available. It was beginning to become clear to me that the ModelFactory API we'd adopted had some inherent limitations, mostly having to do with the creation of unique values and support for namespaced classes. Even still, I hadn't seen anything more appealing until I encountered machinist. Like ModelFactory, you use machinist by defining a set of default properties for your models:

require 'machinist/active_record'
 
User.blueprint do
  name   { "Factory User" }
  login  { 'factoryuser' },
  email  { "#{login}@example.com" }
  active { true }
end
 
class SomeTest < Test::Unit::TestCase
  def test_inactive_user
    assert !User.make(:active => false).active?
  end
end

One of the smartest features of machinist (and one that I borrowed for ModelFactory) is the use of blocks for assigning values. Since these blocks execute in the context of the new instance, it's possible to build values on top of one another. Machinist also includes an additional facility for generating unique values for your test data called Sham. This API can be combined with Faker to generate realistic-looking data for your tests:

require 'machinist/active_record'
require 'sham'
require 'faker'
 
Sham.name  { Faker::Name.name }
Sham.email { Faker::Internet.email }
 
User.blueprint do
  name
  email
  active { true }
end

While a facility for generating unique values is obviously needed, I don't see the advantage of having random, realistic-looking test data. Luckily, the use of Faker is optional:

require 'machinist/active_record'
require 'sham'
 
Sham.name  {|i| "Factory User #{i}" }
Sham.login {|i| "factoryuser#{i}" }
 
User.blueprint do
  name
  login
  email { "#{login}@example.com" }
  active { true }
end

When used in this way, the Sham API seems like an unnecessary component. If all I want is a counter, why not just pass it in to the block generating the values? Here's a example of this technique as it appears in the latest ModelFactory:

require 'modelfactory'
 
ModelFactory.configure do
  default(User) do
    name   {|i| "Factory User #{i}" }
    login  {|i| "factoryuser#{i}" } 
    email  { "#{login}@example.com" }
    active { true }
  end
end

In this case the blocks are still being called in the context of the new instance, but they're also getting a counter passed in when the blocks have a single arity. This is accomplished using the excellent Ruby 1.9 method instance_exec, backported to earlier versions by ActiveSupport.

In this way I can have the best of both worlds while using less code. In order to improve support for namespaced classes, instances are created differently using the new ModelFactory API:

class SomeTest < Test::Unit::TestCase
  def test_inactive_user
    assert !User.factory.create(:active => false).active?
  end
end

For a while I wasn't sure if I wanted to keep ModelFactory around when so many of its problems are solved by other packages. The combination of legacy compatibility and the features described above have granted ModelFactory a reprieve, at least until I find something that I'd rather be using instead.

It's important to evaluate your own solutions for continued relevance, and in the case of ModelFactory it took some work for me to get something that was worth keeping around, given the excellent alternatives. However, whether you use ModelFactory, machinist, Factory Girl or something else entirely, you'll be doing yourself a favor by avoiding stock Rails fixtures.

Tagged as: fixtures, ModelFactory, Ruby on Rails, testing

Project Management - My Two-Year Anniversary at OpenSourcery

This week marks two years for me at OpenSourcery. My first day on the job I walked into a cramped little office, lovingly called The Swamp Castle, in Southeast Portland. At that time, the team consisted of 10 of the smartest individuals I'd ever met, and a cat named Bio. As you can see from Thomas's post, our digs have changed considerably over the last two years. And with the addition of our new intern, Dan Mitu, last month and UI developer, Jackie Scherer, next week - our team will be up to 23.

This spring I anticipate that our Ruby on Rails team will be blogging a lot about the evolution of our approach to agile software development. Just as our development and design processes have matured, we've gained considerable knowledge and experience regarding best practices for agile project management and consistent client communication. Below are just a few of the lessons I've learned regarding agile project management in these first two years at OpenSourcery:

  • No news = The worst news - We often joke amongst both our developers and our clients that software development does not require the administration of penicillin. We know that our work represents a considerable investment on behalf of our clients. We know that deadlines and budgets are really important. And we honestly believe that our open source work is directly changing the world. But ultimately, no one's going to spontaneously combust if something goes wrong - which is a good thing, because something always goes wrong. It's just part of application development. Consequently, we take a very upbeat — but direct and candid — approach to client communication. We don't sugarcoat our project updates or hours reports. We engage our clients as best we can in our decision-making processes. And we document our design goals and development steps using highly transparent tools.
  • Stick to your milestone release schedule - At the start of each agile milestone, we sketch out a target feature set for the milestone release, based on a scoping methodology that generally provides us with consistent results. That being said, as features are developed, the scope and priorities during a milestone inevitably change. When this happens, there's a tendency amongst both clients and development teams to try to adjust release schedules (usually meaning prolonging them) to squeeze in additional features. In our experience, this generally is a mistake. Adjusting milestone scope, rather than milestone duration, requires more project management and client communication. However, sticking to a release schedule ensures more consistent client feedback cycles, more frequent QA, and better management of project budgets.
  • Anticipate, but don't borrow trouble from the future - There's a delicate balance in agile software development between long-term project planning needs and focused, iterative development cycles. It's just human nature to be drawn to the shiny allure of waterfall-style software development - the idea that you can think through every user interaction in an application upfront, build a robust spec - and then chain the developers to their consoles, feed them raw meat and just let them rip. It's tempting as well to try to address every design question that comes up in the development process all at once - as there's something unsettling about releasing features you know aren't complete. But time and again, we've seen that that style of design and development doesn't work. You can't have all the answers, or even know all the questions, upfront. Stay focused on the goals of your current development milestone, and you'll end up with a better, as well as more affordable, product.

Tagged as: Custom Development, Project Management, Ruby on Rails

Zack Hobson named Lead Ruby on Rails Developer

Zack Hobson has been such a stalwart on OpenSourcery Rails projects that he's been promoted to Lead Rails Developer, effective immediately. We're fortunate to have someone of Zack's talent and temperament on the team, and he's shown true leadership on every project he's touched. The most recent examples include his work with CCHIT and a handful of still-too-sensitive to announce startup projects.

Congratulations, Zack!

Tagged as: Ruby on Rails, team

Pronetos Professor's Network

Pronetos Professor's Network built with Ruby on Rails

Pronetos founders Chris Blanchard and Wyatt Werner came to OpenSourcery with the idea of giving academics a network that went beyond mere socializing. They wanted the ability for members to share and review academic papers. Pronetos makes it easy for scholars to stay connected with their colleagues, wherever they may be. Pronetos is a place for scholars to network, and build and share ideas with the greatest minds in their field.

Pronetos is also a content repository that allows readers and authors to interact and build new ideas. Scholars connect as they would at a conference, except this conference is attended by scholars from across the globe. They make interdisciplinary contacts. Exchange ideas. Collaborate. Gain exposure for their research. Stay current on trends in your field. In short, it is THE professor's network.

OpenSourcery built custom features for Pronetos.com with Ruby on Rails, an open source framework designed for rapid web development.

Tagged as: agile, Ruby on Rails, social networking

Wellgram

Wellgram SMS messages

The inspiration for Wellgram comes from numerous studies that show electronic messaging can support health and well-being, and is hugely popular. Yet the tools still aren't widely available in healthcare. That's where Wellgram fits.

Wellgram exists to provide modern messaging to the public, with the versatility to provide a sequence of messages, from anyone to anyone, for free. The power of sequential messaging differentiates Wellgram from other online messaging sites. It's an ideal solution for complex tasks such as medication reminders or simple messages like the popular "Drink Water."

Check out the site for yourself and see what creative ideas people have translated into Wellgrams.

Tagged as: Custom Development, Ruby on Rails, sms

Syndicate content