Comments on: Hexagonal Rails: Objects, Values and Hexagons https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/ Matt Wynne taking it one tea at a time Wed, 21 Aug 2019 12:54:38 +0000 hourly 1 https://wordpress.org/?v=6.2 By: Guerry Semones https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1788 Sun, 04 Nov 2012 13:08:34 +0000 http://blog.mattwynne.net/?p=400#comment-1788 Great topic and very timely! The procedural nature of examples in rails/django/fill-in-the-blank-mvc has been really bugging me recently. I’m very glad the term Hexagonal Architecture in the InfoQ interview intrigued me enough to click. I’m looking forward to the rest of the posts. It looks like Roberto has posted an example of his hexagonal grails project: https://github.com/uris77/tasks

]]>
By: Roberto Guerra https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1742 Wed, 15 Aug 2012 11:07:11 +0000 http://blog.mattwynne.net/?p=400#comment-1742 Oh, and in regards to validation, that belongs in your UI AND your interactors. When you think about it, validations are defined in your use cases. I think the way ORMs are encouraged to be used in these web frameworks have propagated wrong information about what a domain model is. A domain model is how you model a specific domain business rule. What these frameworks refer to as domain models should really be entities. SO if I have a FillApplicationForm interactor, when I call FillApplicationForm.initialize(), I would validate through a private method. If validation fails, I send a response model that can contain the validation errors.

The tricky part to me is to decide if I should send a validation error, or throw an exception. Why is this? Well, I’ve also been toying with command-query pattern and this basically says that if you tell your object to do something, it shouldn’t return a value, and if you tell your object to give you something, it shouldn’t do any complicated transactions. So if I say: FillApplicationForm.getall(), then I don’t expect that call to modify any record in the database. If I say: FillAppplicationForm#updateaddress(params), then that call should not return anything back. This comes in handy when you want to separate your reads and writes into separate dbs also. Anyway, that is another subject. So, the dilemma comes in when something fails. How do I notify the caller that something failed? That is where exceptions come in. I can throw an exception that contains a response model with the errors, and those errors can then be displayed to the user. This is just experimentation. I don’t know anything about CQRS, I’m just trying to learn and this has been my experience with it. I can be totally wrong, but this is what makes sense to me at the moment.

]]>
By: Roberto Guerra https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1741 Wed, 15 Aug 2012 10:44:41 +0000 http://blog.mattwynne.net/?p=400#comment-1741 I really like this topic. Uncle Bob has been given talks lately about this approach:

http://www.confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years

http://vimeo.com/43612849

I’ve been using this approach in 2 new projects I’m working on. One is a groovy project and the other one is a python project.
At first I threw away lots of code trying to figure out how things should go, where to put them, etc. It was getting a little frustrated, but then the light bulb lit. And things are going much smoother now. Tests are blazingly fast, and the code is clean (IMO). So, don’t be afraid to experiment and throw away code. I think sometimes that keeps us back. We invest an entire week on something, and we don’t throw it away even if we realize it is ugly and wrong. This happens alot in the initial phase (at least for me).

As for Steve’s question regarding SRP in hexagonal models: it abides more to SRP than using ActiveRecord, GORM, or Django’s ORM the way they are prescribed to be used in their frameworks. This was the hardest thing for me to grasp, but it eventually kicked in. The persistence is not attached to the domain model, but to the ‘interactors’ as Uncle Bob calls them, or to your use cases. So if I have a use case called: fill application form, then I create an interactor that will do that. That interactor will then call the persistence layer to do the persistence it needs to do. The beauty about it, is that I can inject the persistence service (or repository in DDD terms), and just mock it out for my unit tests. Then I test my repository separate. Like it or not, testing your DB is an integration test by definition. You are integrating your application with a data storage. Something that is external. I can have a ApplicationFormRepository#persist() that will match the use case I’m working on. I can test that in isolation also. And I can use datamapper, ActiveRecord, SQLAlchemy, GORM, MyBatis … whatever ORM to make my life easier. The ORM becomes a tool, a mere detail that can be swapped.

]]>
By: Steve https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1711 Mon, 16 Jul 2012 19:13:06 +0000 http://blog.mattwynne.net/?p=400#comment-1711 s just the beginning.</p> <p>Hexagonal Rails is a very interesting topic and seems to be a pretty new idea in the community. Therefore, it is hard to find a lot of practical examples of how the existing code should be decoupled from the Rails application.</p> <p>One of my biggest concerns is models refactoring. As I understand, in the hexagonal architecture ORM (ActiveRecord / DataMapper) acts as an adapter, and all the code, that calls ORM dependent methods, should be kept inside the model class: attribute definitions, validations, associations, and finders.</p> <p>My two questions are:</p> <ol> <li><p>As the Rails model cannot be tested without invoking Rails with all of its dependencies, does it mean, that my model validations do not belong to business logic, and should not be tested by unit tests? It doesn’t seem to make much sense to test validations at integration level either, since some of the models might be called from UI, others as background tasks, and etc. Then how do I test it?</p></li> <li><p>If ORM acts as an adapter, it means, that there cannot be any Model.find(id) (ActiveRecord) or Model.get(id) (DataMapper) calls outside of the Model class (app/models/model.rb), since that would create a dependency on a specific ORM for the entire application. Nevertheless, if I keep all the model related database calls in the same Model class, doesn’t that break the principles of Single Responsibility (it will contain queries for different behaviors of, for example, User model) and Open/Closed (which will cause endless modifications instead of extensions of the same model)?</p></li> </ol> <p>Again, I am very interested in this topic, but such dilemmas as these make it hard move to Hexagonal Rails camp and I would be grateful for any possible solutions or examples.</p> ]]> Thank you for these articles. I hope it’s just the beginning.

Hexagonal Rails is a very interesting topic and seems to be a pretty new idea in the community. Therefore, it is hard to find a lot of practical examples of how the existing code should be decoupled from the Rails application.

One of my biggest concerns is models refactoring. As I understand, in the hexagonal architecture ORM (ActiveRecord / DataMapper) acts as an adapter, and all the code, that calls ORM dependent methods, should be kept inside the model class: attribute definitions, validations, associations, and finders.

My two questions are:

  1. As the Rails model cannot be tested without invoking Rails with all of its dependencies, does it mean, that my model validations do not belong to business logic, and should not be tested by unit tests? It doesn’t seem to make much sense to test validations at integration level either, since some of the models might be called from UI, others as background tasks, and etc. Then how do I test it?

  2. If ORM acts as an adapter, it means, that there cannot be any Model.find(id) (ActiveRecord) or Model.get(id) (DataMapper) calls outside of the Model class (app/models/model.rb), since that would create a dependency on a specific ORM for the entire application. Nevertheless, if I keep all the model related database calls in the same Model class, doesn’t that break the principles of Single Responsibility (it will contain queries for different behaviors of, for example, User model) and Open/Closed (which will cause endless modifications instead of extensions of the same model)?

Again, I am very interested in this topic, but such dilemmas as these make it hard move to Hexagonal Rails camp and I would be grateful for any possible solutions or examples.

]]>
By: Charles W https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1679 Thu, 14 Jun 2012 06:57:15 +0000 http://blog.mattwynne.net/?p=400#comment-1679 Very interesting post, I’m looking forward to the next article in the series as I recognize too much of my own code in your procedural example!

]]>
By: Vanja Radovanovic https://blog.mattwynne.net/2012/05/31/hexagonal-rails-objects-values-and-hexagons/comment-page-1/#comment-1671 Sun, 10 Jun 2012 14:17:20 +0000 http://blog.mattwynne.net/?p=400#comment-1671 Hi!
I’ve been playing with similar idea lately.

Haven’t completed the cycle, but I do have an example that goes along these lines: https://github.com/elvanja/roar_example
It is still unfinished and perhaps a bit off topic since it was created with the idea to be a showcase for roar gem, but is basically “gemified” into several packages.

Will this series of articles result in something similar? I would like to compare ideas 🙂

And a link that goes through this hexagonal idea too:
http://alistair.cockburn.us/Hexagonal+architecture

Looking forward to reading the rest of the series 🙂
Vanja

]]>