Rethinking your design: slim models, fat presenters?

For me, it started with a tweet from Uncle Bob Martin, saying that if all your domain logic is in your model, or if you put your domain logic inside your models by default, then you are doing it wrong. I think the reasoning behind this is that we should design the domain model before relying on our database model (which is actually an implementation of that domain model). Because the best way to store something in the database is not always to best way to treat or represent or handle the data. In my Rails projects, I have to admit that in most cases the database is my domain model. Which in simple cases is correct, but in more complex cases it is not anymore. Secondly what happens is that your database model could shine through in your UI, or if it does not, your views or helpers could get very heavy. One good way to handle this is to use Presenters. Which goes into the direction of that domain logic, independent of the database. A Presenter is a class that groups all data, knows where to find it, or store it, and will match one-on-one on your presentation/view logic. Thirdly, I went to arrrrcamp, and there was Corey Haines doing his talk about Fast Rails Tests. While this title was very promising, Corey warned us that, in his own words, we would be underwhelmed. This was not entirely true, but not entirely false either :) In short what Corey said was: testing in Rails is slow because we need to drag around the framework, so why not cut out the framework where possible. So he showed an example where he extracted code from models and into separate modules, where you test them standalone. Standalone means: without requiring @spec_helper@. I did this for our modules inside @lib@ where possible, and truth be told: those specs now really fly! Awesome. But the large parts of our test-suite is our models, controllers, views, helpers where this is not possible nor wanted. I want to be able to run our complete test-suite faster, and this was not a solution for that. We scraped a few seconds of our complete time. Extracting code from our models into standalone modules will not make our total test-suite go faster either. Still it is something well worth investigating further. I don't believe in splitting up classes into modules just for the sake of making my tests faster. There has to be some logical reason (pertaining to the domain model --that is). But maybe presenters could be the way out here:

  • they group domain logic
  • while they are responsible for retrieving the correct objects from the database, these actions are just delegated to the responsible models So that sounds promising to me and a road I will investigate.

Comments
Add comment

Recent comments

Tags

ruby on rails 34 ruby 26 rails3 17 rails 15 oracle 11 rspec 9 rspec2 7 jquery 7 ubuntu 5 javascript 5 windows 5 activerecord 3 refactoring 3 geoserver 3 gis 3 arrrrcamp 3 actionmailer 2 oracle spatial 2 tdd 2 postgis 2 routing 2 rvm 2 mongoid 2 csharp 2 thin 2 win32 2 gem 2 rails4 2 git 2 service 2 haml 2 cucumber 2 view testing 2 i18n 1 displaysleep 1 spatial 1 gemsets 1 wubi 1 oracle_enhanced_adapter 1 migrations 1 watchr 1 ci 1 plugins 1 coderetreat 1 ie8 1 ssl 1 oci 1 nested model form 1 wcf 1 11.04 1 jsonp 1 ruby-oci8 1 teamcity 1 engines 1 pgadmin 1 soap 1 content_for 1 word automation 1 plugin 1 capybara 1 xml 1 bootstrap 1 migrate to rails3 1 mvc 1 unity 1 rendering 1 word2007 1 x64 1 limited stock 1 fast tests 1 pl/sql 1 delayed_job 1 pdf 1 test coverage 1 optimization 1 processing 1 borland 1 method_missing 1 cross-browser 1 devise 1 schema_plus 1 mongo 1 mongrel 1 dual boot 1 usability 1 mongrel_service 1 dba 1 mission statement 1 model 1 metadata 1 rcov 1 exceptions 1 image_tag 1 attachments 1 bde 1 css 1 yield 1 ajax 1 generative art 1 rails-assets 1 coordinate systems 1 submodules 1 netzke 1 ora-01031 1 authlogic 1 postgresql 1 shopping cart 1 agile 1 fast_tagger 1 subjective 1 wice_grid 1 generators 1 nvidia 1 mongodb 1 etsyhacks 1 staleobjecterror 1 session 1 jeweler 1 wordpress hacked 1 jasmine 1 heroku 1 rjs 1 life 1 unobtrusive-javascript 1 render_anywhere 1 html5 1 rails31 1 json 1 cocoon 1 mingw32 1 observe_field 1 osx 1 actionwebservice 1 testing 1 debugging 1 strings 1