Lately, we continued engaged on the replace I referred to in my earlier publish.
When planning an replace from Rails 4.2 to Rails 5.0 after which to Rails 5.1, I spotted once more how essential it’s to keep away from coupling your software to the framework’s inner particulars.
As an example the significance of decoupling, let’s take a look at the adjustments in ActionController::Parameters
in Rails 4.2 to five.1.
Rails 4.2
In Rails 4.2, ActionController::Parameters
have been a subclass of Ruby’s core Hash
class, making it straightforward to go round and use like another hash.
Rails 5.0
Rails 5.0 launched a major change: ActionController::Parameters
have been not a subclass of Hash however a separate class fully.
This variation was carried out to enhance safety and forestall mass project vulnerabilities.
Nonetheless, all of the strategies out there on hashes have been nonetheless out there on ActionController::Parameters
by way of the missing_method
hook.
Rails 5.1
In Rails 5.1, the missing_method
hook was eliminated.
It additional emphasised the separation between ActionController::Parameters and common Ruby hashes in order that strategies #every
, #map
, #each_key
, #each_value
, and so on., have been not out there on ActionController::Parameters
situations.
As you possibly can see, the distinction in public API differs considerably between the next Rails variations.
Rails 4.2 | Rails 5.0 | Rails 5.1 | ||||
---|---|---|---|---|---|---|
solely permitted params? | has detached entry? | solely permitted params? | has detached entry? | solely permitted params? | has detached entry? | |
params.to_hash | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ |
params.to_h | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
params.(some native hash technique) | ❌ | ✅ | ❌ | ✅ | Lacking technique error |
The app we have been engaged on has its service layer known as from the controllers.
The service layer is accountable for dealing with some enterprise logic. Its consequence is usually endured within the database.
Sadly, the service objects have been initialized with ActionController::Parameters
situations.
In multiples locations they have been checked in opposition to an inheritance from Hash
:
# ...
return outcomes except hash.kind_of?(Hash)
# ...
They have been even handed to the storage layer and serialized with ActiveModel serialize
technique.
class Attachment < ActiveRecord::Base
serialize :knowledge, Hash
# ...
finish
When attempting to improve Rails, current exams began to fail. We noticed a bunch of ActiveRecord::SerializationTypeMismatch
errors.
A seemingly easy Rails improve turned out to be time-consuming as a result of the area providers have been coupled to the internals of ActionController
module.
To keep away from such issues, it’s essential to keep up a transparent boundary between area logic and framework internals.
Concentrate on passing round framework objects to your area layer. Use normal Ruby varieties or your personal worth objects as a substitute.
Decoupling has a number of benefits:
- Flexibility: Decoupling permits builders to change frameworks, libraries, and even languages with out having to rewrite the whole software.
- Testability: When area logic is decoupled from framework internals, it’s simpler to check the core performance with out advanced setups or dependencies.
- Maintainability: Decoupled purposes are simpler to keep up as a result of they’ve a clearer separation of considerations, making it simpler to determine and repair points.
Related examples can be addressed within the upcoming Rails Enterprise Logic Masterclass course. Subscribe to the publication under so that you don’t miss any updates.