Posts tagged ‘Rails’

July 30, 2010

Yesterday we launched Realized-app.com in a no cost, preview phase.

As previously mentioned, Realized-app began as a simple Ruby on Rails demonstration project. Quickly the proof of concept became a viable app, due mainly to the developer productivity that Rails provides.

For a preview of its capabilities, check out the product tour.

With nearly 60 models in this release, Realized-app represents a relatively modest Rails app. For those developers who would like to explore the app, you are welcome to sign up for free and try it.

Some months ago we adopted delayed_job as our asynchronous background processor. In Realized-app several tasks, particularly tax lot setup, benefit from background processing.

Taking the advice from this blog post on GitHub, we reduced the coupling between models and the message queue by placing the background methods in lib/msg_queue.rb.

module MsgQueue
class UserActivationConfirm < Struct.new(:user_id)
def perform
user = User.find(user_id)
user.activation_confirmation_email
end
. . .

We create the corresponding delayed job in models/user.rb.

class User
def activation_confirmation_mq
mq = MsgQueue::UserActivationConfirm.new(id)
Delayed::Job.enqueue(mq)
end
end

The call to Job#enqueue remains within each model to allow for passing a priority parameter, should that be needed.

Deployment on Heroku

Heroku began limited support for delayed_job in July. Yesterday Heroku broadened that support with a new feature that provides for multiple delayed_job workers per app. That capability sealed our decision to deploy, at least initially, on Heroku.

Some of the more rudimentary aspects of unit testing involve validation. These tests may exercise ActiveRecord or the database constraints created by a migration.

In a chapter from Enterprise Rails, ‘Database As a Fortress’, author Dan Chak advocates for employing the data integrity features of modern databases, particularly PostgreSQL. With Realized-app, we use PostgreSQL as a persistent data store.

To go beyond just testing the ActiveRecord model validations, in testing a database constraint Dan suggests using the following test_helper.rb method:

def expect_db_error(&block)
begin
yield
rescue ActiveRecord::StatementInvalid
database_threw_error = true
rescue
something_else_threw_error = true
end
assert !something_else_threw_error, 'defective case'
assert database_threw_error && !something_else_threw_error
end

One difficulty with testing database constraints is that the ActiveRecord model validations may catch some errors before they reach the PostgreSQL database. As a work-around, we can add another method:

def svf(obj) obj.save_with_validation(false) end	

Using these test helpers, this test will properly exercise the database constraints defined by a migration.

test 'name too long' do
expect_db_error { svf(some_model_save(:name => 'name_too_long')) }
end

Such validation tests tend to be similar among different models. Just as concerned_with allowed for division of model logic into discrete files, we place unit test validation tests in a separate /test/unit/validation directory. This prevents cluttering model-specific logic with boilerplate validation checks.

Several models within our web app, Realized-app, have grown to more than 500 lines. Rapidly grasping the relationships among methods in these models had become difficult. Some means of dividing the models into coherent pieces was needed.

An elegant fix came about while reading the code for the rails-based forum, altered_beast. First, app/models contains a ‘user’ directory. Near the top of models/user.rb, also note a call to concerned_with:

class User < ActiveRecord::Base
concerned_with :validation, :states, :activation, :posting
. . .

One of the rails initializers defines concerned_with. Four files named by the symbols passed to concerned_with reside in app/models/user. The user methods pertaining to validation are found in models/user/validation.rb. Without the separation provided by concerned_with, this validation logic would exist in models/user.rb.

Using concerned_with, we have refactored the largest models in Realized-app. Now, at a glance, most of the functionality unique to a particular model becomes readily apparent.

For a good perspective on the origin of concerned_with and how to use it, see this post by Paul Barry.

A year ago, Paul Graham listed a few Startup Ideas We’d Like to Fund.

#21: “Finance software for individuals and small businesses. Intuit seems ripe for picking off. The difficulty is that they’ve got data connections with all the banks. That’s hard for a small startup to match. But if you can start in a neighboring area and gradually expand into their territory, you could displace them.”

We all watched as Mint entered that space. But both Quicken and Mint fall short when it comes to handling stock investments. Their data connections with financial institutions provide real convenience, but pose issues of security and privacy.

The web is full of personal finance sites with ideas about buying stock. Few address the problem of selling stock from a portfolio to minimize realized capital gains and maintain balanced diversification. And even fewer calculate capital gains and support the preparation of Schedule D.

To maintain privacy, rather than relying on a direct import from each broker, Realized-app uses the FasterCSV gem to import trade history from a .csv history file.

Realized-app began as a Ruby on Rails demonstration project. Time will tell whether security and privacy trump convenience.