Question

In ASP.NET MVC applications and Java web applications, there's a common practice of keeping business logic in a separate package/dll and treating things like the database and delivery mechanisms (web application, web service, native mobile or desktop, etc.) as details that are plugged in.

Some of the advantages of this type of structuring I can tell are:

  • Reuse of the business logic with different delivery mechanisms or persistence layers
  • It's possible to run acceptance and unit tests of the business logic without having to load up a web framework or connecting to a database; the tests are very fast
  • Thinking of the application in terms of what it is, not how it is delivered

But this practice is not common in the Rails community; I don't see any Rails application where the business logic is kept in gems and the main ORMs all tie together persistence logic and business logic. Is there something about Ruby that makes structuring applications in the way I mentioned unnecessary?

Was it helpful?

Solution

Define "necessary". It's not necessary to do this in .NET or Java, it's convenient.

Rails apps often only expose the web app and related services completely within a single app.

Testing is similar; there's no need to break up application functionality in order to test code separately, and testing in Rails is no different: there are unit tests, specs, etc. which can run at any level of the code, and various mechanisms to mock out arbitrary portions of functionality.

Persistence layers are generally handled by the AR layer, although in practice it's fairly unusual to actually switch persistence layers (I've done so exactly once in thirty years of development, but that's anecdotal, obviously). In addition, some such switches in Ruby are transparent at the code level because of duck typing (e.g., I switched one app from a local DB to a service, almost transparently, by moving to ActiveResource instead of ActiveRecord, although I did not try to optimize anything afterwards, and the data model was pretty simple.)

All this said, IMO the Rails community has often overlooked practices from "enterprise" shops because Ruby-the-language makes it very easy to build functionality without a need to over-architect. The limitations of this only become clear after apps reach a certain size, however.

Recent trends in Ruby and Rails development include things I've done in the enterprise for years (and are much easier to implement in Ruby than, say, Java). Breaking out functionality into libraries for its own sake, though, isn't particularly useful. Identifying code that should be broken out is, but that happens across environments, when it's necessary to do so.

OTHER TIPS

Rails is all about convention over configuration. And its opinion / best practices that have been set forth.

I don't see a big advantage to breaking down the BLL into Gems. Unless I have code that is independent of my web app and can be reused. For example I built a BBCode parser for a company forum recently so I packaged that up as a GEM that can plug into any rails app. There are thousands of GEMs on github that extend rails functionally.

The whole idea of making a GEM for a rails app should be code reuse. If you're separating your code just to try and follow more code separation then you're not relying on the rails conventions and if any other rails developers come on to your project they will have a learning curve.

You can use any number of testing systems that don't load the web framework in rails. Testing in a whole huge topic I'd look into RSpec and much more. And there are some ways to speed up testing (such as using Guard and Spork)

It all depends on the app really. The idea of Rails is to get your application done quickly. Java development in my experience has been painfully slow. Same for ASP. But those may have just been "bad experiences." Plenty of people swear by both.

Mostly, it's just about effort and configuration. Let's break down the individual points:

Effort: Setting up a new gem takes a little bit of time (and every project has its own particular set of dependencies - testing, mocking, documentation, etc)

Configuration: Since most Rails apps use ActiveRecord; it is a little more difficult to split out your model layer (though plenty of gems do this). Rails::Engine helps a good deal to mitigate the pain around that, though.

Cost: For most Rails projects, there's very little that you gain by splitting your code out into a separate gem/repo:

  • Most projects are not sharing code between each other (and when they do, they do set up gems)

  • There is - or should be, with proper setup - no difference to how you test the code; either in a gem or in your main project. (You can test models w/o hitting your controllers, etc - no problem)

  • The main benefit is to enforce explicit contracts between interfaces/layers - and that is just less prevalent in the Ruby community

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top