Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails with Repository Pattern?

After working with ASP.Net MVC, it has me thinking about Rails. I worked with Rails prior, but am a little rusty. ASP.Net MVC tutorials recomment hiding data layer implementation with the repository pattern. This allows easiesr Dependency Injection for Unit Testing, and nice decoupling of the controller from the model implementation.

I remember Rails’ controllers using Active Record objects directly, and unit tests using test databases that could be setup and torn down with ease. That solves the need to swap out for unit testing, but still it seems like a bad idea to have so much ActiveRecord code exposed in the controller.

So my question is, what is the latest best practice here? Are real (not mocked) databases still used for unit testing? Do Rails developers call ActiveRecord directly, or an abstraction?

like image 794
Tim Hoolihan Avatar asked Nov 03 '09 23:11

Tim Hoolihan


People also ask

What is a repository in Ruby?

"A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer.

Should I use Repository pattern?

The Repository pattern makes it easier to test your application logic. The Repository pattern allows you to easily test your application with unit tests. Remember that unit tests only test your code, not infrastructure, so the repository abstractions make it easier to achieve that goal.

What type of design pattern is repository?

To put it simply, Repository pattern is a kind of container where data access logic is stored. It hides the details of data access logic from business logic. In other words, we allow business logic to access the data object without having knowledge of underlying data access architecture.

What are design patterns in Rails?

Design patterns are typical solutions to common problems in software design. Each pattern is like a customizable blueprint used to solve a particular design problem in your code. They define a language that efficiently improves team communication.


2 Answers

Does ActiveRecord even really constitute the "data layer", I wonder? After all, its purpose is to abstract (to a fairly reasonable extent) the actual interaction storage. If I have a model that inherits from ActiveRecord::Base and I reference that model in a controller, am I really interacting with the data layer?

Looking at a brief description of the Repository Pattern I'd say that methods of the find_by_ are already giving you much of what it describes, which is good, isn't it? OK, the abstraction layer is leaky (one might more generously say "pragmatic") in that we can go a lot closer to the metal if need be, and find_by_sql for example will pretty much make it obvious that we're dealing with a relational database of some kind.

I'd recommend never (or maybe I should say "rarely and not without extreme justification" - it's always tricky using absolutes) putting code in controllers that makes it possible to infer the data platform being used. It should all be pushed into the models - named_scope can be very useful here. For complex results, consider using "presentation" objects as the interface (Struct and my personal favourite OpenStruct can be very useful here).

While ActiveRecord is the de facto standard, given that it installs with Rails, it's not the only game in town. For non-SQL databases, something different is necessary, but even in the SQL domain there's Datamapper (is that based on the eponymous PoEAA pattern?)

In Rails 3.0 it's going to be a lot easier to pick and choose components such as the ORM as Yehuda and the boys unpick and clean up the interfaces.

like image 146
Mike Woodhouse Avatar answered Oct 15 '22 23:10

Mike Woodhouse


My experience has been that Ruby on Rails integrates ActiveRecord so tightly (in most cases, it can become nearly completely transparent) that developers often use it without any Abstraction.

The thing to remember is that the Repository pattern and the Active Record pattern were both suggested in Patterns of Enterprise Architecture by Martin Fowler (which, if you haven't read it yet...you should). Active Record is tightly integrated in Rails. Microsoft .NET doens't tie you to a pattern...so the Repository pattern was adopted by the majority of the developers.

like image 40
Justin Niessner Avatar answered Oct 15 '22 22:10

Justin Niessner