SlideShare a Scribd company logo
This page was intentionally left blank.
or... rethinking Rails architecture
...if there's any.
Rails new way
A few facts about me
Blogger
kamil.lelonek.me
Live in
Wrocław,
Poland
CTO at
woumedia,
Denmark
Full-stack Developer
(mostly Ruby, Scala)
@KamilLelonek
DCI
DDD
CQRS
Event Sourcing
Actor model
Reactive programming
Microservices
Service objects
What won't be about?
No fancy
stuff
What will be about then?
Why?
evel, everything in Rails is crying for separation
For every Rails project, there are exactly two outcomes.
Either they can be well
designed.
or you will struggle a lot when
maintaining them.
Because there is no architecture.
So why a conventional Rails architecture fails?
Why to rails-way at all in that case?
When not to rails way?
Where's the problem?
simplicity vs maintainability
models with thousands of lines of code
following the Rails conventions
What are we doing?
What is the solution?
MVC
?
So, why do we need Rails?
Rails needs more abstraction layers.
time to refactor
It's
Value Objects
immutable no identity
Entities
differs by ID stateful
Mappers
ActiveRecord -> Domain Object
Renaming,
Coercing, ...
Form Objects
Validation User input -> Domain Object
Repositories
DAO Infrastructural layer
Queries
Wraps query logic Query API
Validators
Ensure valid models Ensure valid data
Use cases
Slim down controllers Data flow orchestration
Testing
Features
No more "where do I put this kind of logic?"
Clean architecture and right order
A lot of boilerplate
Not very useful for simple domain
Infrastructure
Resources
https://github.com/KamilLelonek/rails-new-way/
https://github.com/KamilLelonek/react-new-way/
http://bit.ly/controversial-service-objects
http://bit.ly/ddd-dictionary
http://bit.ly/decouple-from-activerecord
Q&A
Thank you for having me here
rails new app --skip-rails

More Related Content

Similar to Rails New Way

It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.
cschaafsma
 
Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
Andrew Lovett-Barron
 
Server-side Web development via Ruby on Rails
Server-side Web development via Ruby on RailsServer-side Web development via Ruby on Rails
Server-side Web development via Ruby on Rails
g3ppy
 

Similar to Rails New Way (20)

Ruby on rails
Ruby on railsRuby on rails
Ruby on rails
 
If NoSQL is your answer, you are probably asking the wrong question.
If NoSQL is your answer, you are probably asking the wrong question.If NoSQL is your answer, you are probably asking the wrong question.
If NoSQL is your answer, you are probably asking the wrong question.
 
The CQRS diet
The CQRS dietThe CQRS diet
The CQRS diet
 
AWS case study: real estate portal
AWS case study: real estate portalAWS case study: real estate portal
AWS case study: real estate portal
 
Moving from Relational to Document Store
Moving from Relational to Document StoreMoving from Relational to Document Store
Moving from Relational to Document Store
 
Domain oriented development
Domain oriented developmentDomain oriented development
Domain oriented development
 
On nosql
On nosqlOn nosql
On nosql
 
NoSQL
NoSQLNoSQL
NoSQL
 
Ruby On Rails Overview
Ruby On Rails OverviewRuby On Rails Overview
Ruby On Rails Overview
 
Ruby Metaprogramming 08
Ruby Metaprogramming 08Ruby Metaprogramming 08
Ruby Metaprogramming 08
 
A Tour of Ruby On Rails
A Tour of Ruby On RailsA Tour of Ruby On Rails
A Tour of Ruby On Rails
 
NoSql Databases
NoSql DatabasesNoSql Databases
NoSql Databases
 
It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.It's OK to make a new folder within Rails.
It's OK to make a new folder within Rails.
 
No Sql
No SqlNo Sql
No Sql
 
Intro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate JavascriptIntro to BackboneJS + Intermediate Javascript
Intro to BackboneJS + Intermediate Javascript
 
Server-side Web development via Ruby on Rails
Server-side Web development via Ruby on RailsServer-side Web development via Ruby on Rails
Server-side Web development via Ruby on Rails
 
CQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architectureCQRS recipes or how to cook your architecture
CQRS recipes or how to cook your architecture
 
Ruby On Rails
Ruby On RailsRuby On Rails
Ruby On Rails
 
Beyond rails new
Beyond rails newBeyond rails new
Beyond rails new
 
Minnebar 2013 - Scaling with Cassandra
Minnebar 2013 - Scaling with CassandraMinnebar 2013 - Scaling with Cassandra
Minnebar 2013 - Scaling with Cassandra
 

More from Kamil Lelonek (8)

Angular2 ecosystem
Angular2 ecosystemAngular2 ecosystem
Angular2 ecosystem
 
Elixir metaprogramming
Elixir metaprogrammingElixir metaprogramming
Elixir metaprogramming
 
Introduction to Web Security
Introduction to Web SecurityIntroduction to Web Security
Introduction to Web Security
 
Crystal
CrystalCrystal
Crystal
 
Ansible
AnsibleAnsible
Ansible
 
Scala vs ruby
Scala vs rubyScala vs ruby
Scala vs ruby
 
A brief intro to RubyMotion
A brief intro to RubyMotionA brief intro to RubyMotion
A brief intro to RubyMotion
 
oAuth wroclove
oAuth wrocloveoAuth wroclove
oAuth wroclove
 

Recently uploaded

Additional Benefits for Employee Website.pdf
Additional Benefits for Employee Website.pdfAdditional Benefits for Employee Website.pdf
Additional Benefits for Employee Website.pdf
joachimlavalley1
 
Industrial Training Report- AKTU Industrial Training Report
Industrial Training Report- AKTU Industrial Training ReportIndustrial Training Report- AKTU Industrial Training Report
Industrial Training Report- AKTU Industrial Training Report
Avinash Rai
 
plant breeding methods in asexually or clonally propagated crops
plant breeding methods in asexually or clonally propagated cropsplant breeding methods in asexually or clonally propagated crops
plant breeding methods in asexually or clonally propagated crops
parmarsneha2
 

Recently uploaded (20)

The Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official PublicationThe Challenger.pdf DNHS Official Publication
The Challenger.pdf DNHS Official Publication
 
Students, digital devices and success - Andreas Schleicher - 27 May 2024..pptx
Students, digital devices and success - Andreas Schleicher - 27 May 2024..pptxStudents, digital devices and success - Andreas Schleicher - 27 May 2024..pptx
Students, digital devices and success - Andreas Schleicher - 27 May 2024..pptx
 
Jose-Rizal-and-Philippine-Nationalism-National-Symbol-2.pptx
Jose-Rizal-and-Philippine-Nationalism-National-Symbol-2.pptxJose-Rizal-and-Philippine-Nationalism-National-Symbol-2.pptx
Jose-Rizal-and-Philippine-Nationalism-National-Symbol-2.pptx
 
Sha'Carri Richardson Presentation 202345
Sha'Carri Richardson Presentation 202345Sha'Carri Richardson Presentation 202345
Sha'Carri Richardson Presentation 202345
 
Additional Benefits for Employee Website.pdf
Additional Benefits for Employee Website.pdfAdditional Benefits for Employee Website.pdf
Additional Benefits for Employee Website.pdf
 
How to Create Map Views in the Odoo 17 ERP
How to Create Map Views in the Odoo 17 ERPHow to Create Map Views in the Odoo 17 ERP
How to Create Map Views in the Odoo 17 ERP
 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 
50 ĐỀ LUYỆN THI IOE LỚP 9 - NĂM HỌC 2022-2023 (CÓ LINK HÌNH, FILE AUDIO VÀ ĐÁ...
50 ĐỀ LUYỆN THI IOE LỚP 9 - NĂM HỌC 2022-2023 (CÓ LINK HÌNH, FILE AUDIO VÀ ĐÁ...50 ĐỀ LUYỆN THI IOE LỚP 9 - NĂM HỌC 2022-2023 (CÓ LINK HÌNH, FILE AUDIO VÀ ĐÁ...
50 ĐỀ LUYỆN THI IOE LỚP 9 - NĂM HỌC 2022-2023 (CÓ LINK HÌNH, FILE AUDIO VÀ ĐÁ...
 
Industrial Training Report- AKTU Industrial Training Report
Industrial Training Report- AKTU Industrial Training ReportIndustrial Training Report- AKTU Industrial Training Report
Industrial Training Report- AKTU Industrial Training Report
 
Home assignment II on Spectroscopy 2024 Answers.pdf
Home assignment II on Spectroscopy 2024 Answers.pdfHome assignment II on Spectroscopy 2024 Answers.pdf
Home assignment II on Spectroscopy 2024 Answers.pdf
 
Fish and Chips - have they had their chips
Fish and Chips - have they had their chipsFish and Chips - have they had their chips
Fish and Chips - have they had their chips
 
PART A. Introduction to Costumer Service
PART A. Introduction to Costumer ServicePART A. Introduction to Costumer Service
PART A. Introduction to Costumer Service
 
INU_CAPSTONEDESIGN_비밀번호486_업로드용 발표자료.pdf
INU_CAPSTONEDESIGN_비밀번호486_업로드용 발표자료.pdfINU_CAPSTONEDESIGN_비밀번호486_업로드용 발표자료.pdf
INU_CAPSTONEDESIGN_비밀번호486_업로드용 발표자료.pdf
 
Palestine last event orientationfvgnh .pptx
Palestine last event orientationfvgnh .pptxPalestine last event orientationfvgnh .pptx
Palestine last event orientationfvgnh .pptx
 
The approach at University of Liverpool.pptx
The approach at University of Liverpool.pptxThe approach at University of Liverpool.pptx
The approach at University of Liverpool.pptx
 
plant breeding methods in asexually or clonally propagated crops
plant breeding methods in asexually or clonally propagated cropsplant breeding methods in asexually or clonally propagated crops
plant breeding methods in asexually or clonally propagated crops
 
How to Break the cycle of negative Thoughts
How to Break the cycle of negative ThoughtsHow to Break the cycle of negative Thoughts
How to Break the cycle of negative Thoughts
 
Basic_QTL_Marker-assisted_Selection_Sourabh.ppt
Basic_QTL_Marker-assisted_Selection_Sourabh.pptBasic_QTL_Marker-assisted_Selection_Sourabh.ppt
Basic_QTL_Marker-assisted_Selection_Sourabh.ppt
 
Chapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptxChapter 3 - Islamic Banking Products and Services.pptx
Chapter 3 - Islamic Banking Products and Services.pptx
 
The Art Pastor's Guide to Sabbath | Steve Thomason
The Art Pastor's Guide to Sabbath | Steve ThomasonThe Art Pastor's Guide to Sabbath | Steve Thomason
The Art Pastor's Guide to Sabbath | Steve Thomason
 

Rails New Way

Editor's Notes

  1. Hello guys, in this presentation we're gonna rethink Rails architecture together, discuss some pitfalls > and propose some solutions for a better development process.
  2. At the very beginning I'd like to clarify what we won't talk about directly. > It won't be about ... > and some other fancy stuff. But still you don't know what to expect, right?
  3. So, I can ensure that I will mention about Value Objects, Entities, Queries and Repositories. > I'll try to present and describe a lot of useful building blocks for modern applications.
  4. What is the reason for rearranging something that is already done? Well, when it's done poorly, it's worth to review it, because ... But those cries go unheard, mostly.
  5. Nowadays, Rails applications can end up in two ways: > Either someone in the team is an experienced architect and leads the software to an advanced design with service layer, view components, maybe forms, and so on. > or a classy way, when a project strictly follows the Rails Way and will end up as a code disaster.
  6. I would like to apologise to anyone I have offended. And to those I haven't offended yet. Please be patient. I will get to you shortly.
  7. Based on what I said you may wonder now when to follow the Rails way without introducing any additional architecture. There are some cases when that may be useful. > It's easy to learn and add new features, you can simply add new concepts by running scaffolding. > For fast production-ready or production-convertible prototypes that you need to present to your potential customer as a proof of concept. > It allows you to simple jump between different projects without diving into a custom architecture > Perfect for CRUD applications of course.
  8. However, usually you build bigger apps. You have a way more complex problems and provide not so simple solutions. There's when an additional architecture comes handy. > When you maintain long-term projects > In case you have experienced programmers who probably want to try something more > When your domain is big and business logic is complex > When your team is distributed
  9. > Once again, did we fall into some kind of trap? What price do we pay for Rails’ simplicity in trade for maintainability? Were we tempted by this simplicity without thinking about the maintenance? > Is it worth writing models with thousands of lines of code and building a throw-away software kludge that is impossible to maintain, just for the sake of development speed? > How fast are we on the very beginning compared to the future development? Is it worth blindly hacking away and following the Rails conventions without thinking about whether this is the right place for that code?
  10. Here is how the majority of applications are created these days. We just do rails new and that's it.
  11. And here is how it actually should be done. rails-api is an awesome gem that let you build applications which expose RESTful endpoints with JSON data for separated frontend apps.
  12. Rails downright encourages us to write big, monolithic applications in an MVC manner instead of splitting them into separate layers or a hexagonal architecture. Right now, instead of identifying and implementing new layers like form objects, things get violently pressed into the controller or alternatively the model, both in the framework itself and in your application code. All that just because of fearing over-abstraction. > Why on earth is Rails constantly trying to solve incredible complex problems in one gigantic, monolithic class?
  13. ... Should we drop Rails at all? After all we have great frameworks such are > Lotus > Volt > or rom-rb? BTW, anyone use either of them?
  14. We can still use Rails, but ...
  15. The first building block to refactor our applications is a Value Object. > Value object  is  an immutable object that describes some characteristic or attribute > but carries no concept of identity.
  16. This is an example of Value Object. I'm using Virtus gem from a friend of mine which provides nice helpers for value objects. We can specify attributes and their types.
  17. Entity  is  an object fundamentally defined not by its attributes. > It differs by ID, which have to be unique within an aggregate, not necessary globally. Never share an entity between aggregates. > A unique thing that has a life cycle and can change state. Sometimes in one context something is an entity while in another it is just a value object. (Aggregate — a cluster of domain objects that can be treated as a single unit to provide a specific functionality and for the purpose of data changes) Can you find some examples of that?
  18. Once again using Virtus, we can easily create Entity with given attributes and their types.
  19. Taking data from one representation and converting it into another is done by using mappers. > Mapper is an object that takes a record and turns it into a domain object. You can design your domain objects exactly the way you want and configure mappings accordingly. By defining a mapper you are specifying which entity class is going to be instantiated and what attributes are going to be used. > Mapping is an extremely powerful concept. It can: Rename attributes Coerce values Build aggregate objects Build immutable value objects ...
  20. This is a mapper that takes a record from a DB and turns is into a domain object with particular attributes.
  21. Submitting form data is a common feature of web applications – allowing users to submit their information > and giving them feedback whether the information is valid or not. And for that purpose we use form objects. > Form Object is an object that wraps incoming input from a user and provides a validation to ensure that only correct data is processed within an application anytime later.
  22. And this is an example where I'm using Reform gem from my another friend @apotonick and this gem is used to wrap user's input, validate it, and map it into a particular entity. So from given params we get completely valid domain object.
  23. > Repository — mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. > A repository implementation is also an example of an infrastructural service. Therefore the specifics of the communication with durable storage mechanisms are handled in the infrastructure layer.
  24. Our repository uses Dependency Injection to accept a particular adapter, which can be ActiveRecord during development and production or InMemoryAdapter while we are testing our code. Later on we use injected adapter to create and store a particular object from our form object.
  25. Database queries, even simple ones, can be both repetitive and hard to read and comprehend. With more complex queries, especially ones that embed data from multiple collections or tables, this process can get messy to write and even messier to maintain. > Query object - provides a nice tool for extracting query logic and associated operations into a contained module, pulling the logic out into a more maintainable and readable structure, > while also providing a very readable API where the query object is used.
  26. In this query we are finding a record by it's id and then we map it onto our domain entity object. In case of failure we raise not found error.
  27. > Validators - are used to ensure that only valid models exist within your application > and therefore only valid data is saved into your database. It may be important for your application to ensure that every user provides a valid email address and a phone number in a correct format. There are several ways to validate data before it is saved into your database, including native database constraints, client-side validations, controller-level validations, but validators wrap all of them in a one place together.
  28. This is an example of a validator that just checks if given params conform our form object constraints. There's no DB checking and other kind of validations.
  29. > Use case - a component that is responsible for the coordination logic we tend to put into our controllers. And being a coordinator, a use case should not do any computation or state management. There is no one-to-one mapping between use cases and controllers. One controller can support multiple different use cases and vice versa. > These use cases orchestrate the flow of data to, and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.
  30. In this example I use solid-use-case gem which helps define steps for a specific flow. So when making an order we can validate incoming params, sore the result and dump read model into our database.
  31. How fast are your tests? Do they rely on a database? How easily can you switch from relational schema to NoSQL documents or even YAML store? Do you have fat Models that leak up to Controllers or even Views? Does your application depend on details of a particular ORM implementation?
  32. Using previously described building blocks we can easily avoid aforementioned problems. We define in-memory adapter that behaves similarly to active record and can be injected into our repositories.
  33. Here you can see an example usage of it. We are creating an in-memory adapter and inject it in our repository that we are using later. In more complex cases we can define an in-memory repository instead of just an adapter.
  34. And that's all of the building blocks for now. I didn't mentioned about Service Objects, but it's a topic for yet another talk. > What are the possible disadvantages of them? ... > And what about benefits?
  35. With a new architecture comes a new infrastructure as well.
  36. In this picture I'm showing you an overall flow within the recent startup I've been doing. I will focus on particular parts right now.
  37. Firstly, I've extracted a front-end part completely. I don't have views served by a rails application. Instead, I have a couple of lightweight front-end static single page applications build, compiled and minified using Brunch or Middleman with all goodness from CDN servers. They are using REST API to connect with backend application.
  38. The backend is divided as well. I'm using one core rails-api server, which connects to 3 different micro services using CQS flow, vertx queuing system and their own separated databases. Each microservice describes one bounded context and wraps a specific responsibilities that are called from the core server.
  39. Besides the benefits I'be told you already there is also a note about deployment. I can independently deploy either front-end application or even a micro-service. Using pipelines and integration server I can easily extend only some part of my application which is extremely fast and efficient.
  40. Here are some resources I'd like to share with you. I've written a couple of blogposts related to the presented topic. Moreover, I created a sample application to show you working examples with discussed building blocks.
  41. Well, that's it for now. Have you guys any questions for me?