Are you sure?
Decorators decorate your class with new set of functionality.
What are your decorators doing? Adding a few rendering specific methods to a class to help with rendering? Perhaps you should consider Presenters. But better: how will it scale, can it be grouped, will it really add the simplification. Be wary of too quick branching off functionality to decorators. Most cases I've seen them were overly architectured, and they didn't bring much value.
One might consider using Concerns or mixins as an alternative. The disadvantage here is that your main object gets more public methods, but I consider it as a feature after having experienced too much potentially reusable functionality grouped arbitrarily away in other presenter / decorator classes.
So I wrote a few short articles on when to use FormObjects and Jobs and ServiceObjects. The question is of course "it depends", but the leading principle I have is keep it simple. That being said, for inspiration, some suggestion for different layers to manage the application complexity from Vladimir Dementyev's talk on Railsconf:
Whenever your model gets too heavy?
The easiest way to clean up your classes might be to create smaller, more concise methods. The next easiest way of tiding up your models is moving stuff to modules (whether they are 'Concerns' or not). Modules can then be included in the final classes. It will lead to a crowded list of methods exposed on these classes, for which alternative solutions exist (Presenters, Decorators), but if you shield off private methods nicely and have a consistent way of naming things, I wouldn't be too concerned about that. Note that having many modules used in only a single class might be a code smell: perhaps you're trying to do too much with that single class.
When you're using Rails, you can make use of Concerns. They offer a few advantages over traditional modules, so use it whenever you're bothering recreating the same behaviour using plain old ruby Modules. I prefer consistency, so if you've adopted Concerns, use con…
When necessary.
It depends. By default I would advise against them; not creating Form objects to receive and validate data that could be validated by the Model directly. Even when you have a few nested attributes that belong to the main model modified, I would advise against Form objects. Keep It Simple.
But… sometimes you have more complex forms that don't fit the database-mirroring ActiveRecord model as nicely.
Always.
When you are able to do stuff async (not blocking the web-request), make it async. It will also reduce the need for a category of Service-objects. Worker or Job objects can often be called inline if desired.
Sidenote: I personally prefer the "Job" object name, a Job that needs to be performed. Worker is a name that was popularised by Sidekiq, but Sidekiq moved to Jobs as well.
Never.
There is of course never an absolute answer to stuff but if you are running it in a background job anyway have you considered directly writing it in a Worker or Job-object? Note that you can always run jobs async when needed.
My main objection against service objects is that all too often they are ill defined as a category. So while having fat controllers or fat models may be a bad thing, just creating a bunch of somewhat arbitrary 'Services' is not making the code more manageable.
When considering adding a 'services' directory to your app, try to think of what class of problems you want to tackle. And when in doubt, just keep messing around with the somewhat fatter models & controllers.
I'm still a big fan of Ruby on Rails. No other framework has ever made me as productive. And it is no a secret that it makes quite some other product companies very successful. Think of Shopify, Github, Basecamp, Hey, and others.
But if you'd look at at the list of most popular languages, the top 10 doesn't feature ruby anymore.
In their 2020 survey on most popular technologies, StackOverflow writes:
> Additionally, Ruby, once in the top 10 of this list as recently as 2017, has declined, being surpassed by newer, trendier technologies such as Go and Kotlin.
Also if you look at Google trends, ruby has always been negligible when compared to Python or PHP or Javascript, [the trend is downward for the ruby package manager](https://trends.google.nl/trends/explor…
A quick note, because I was using the wrong search terms. If you want to share e.g. the current user of an app with a model you can now (since Rails 5.2) use a model inheriting from ActiveSupport::CurrentAttributes. Before you were required to pass this current user explicitly or find another way to access state.
Note that this can either be a good thing or a bad thing (tl;dr: thread-local global state makes apps unpredictable)
And even the docs warn against abusing this feature. Powerful tools can come with dangerous consequences :) Global variables are immensely powerful. Use with care. I'm not even sure if I'm going down this path…
Prometheus is a statistics collecting tool that originated from SoundCloud. Designed to be used in high performance environments, it is build to be blazingly fast. Hence, the client typically is expected to be blazingly fast as well, gathering and presenting data within nanoseconds. For Ruby on Rails applications however this has lead to an unresolved issue with the Prometheus ruby-client when the same application is forked (typical for Puma, Passenger and other popular ruby-servers). The Prometheus client collects data within its own fork before serving it to the exporter endpoint. This can or cannot be a problem. When you measuring response times, running averages from a random fork may be good enough. However, when you're also counting data over time you're having separate counters in …
Webpacker is still opt-in for new Rails projects. But this might change. The JavaScript ecosystem is moving fast and new JavaScript frameworks are pushing customer’s expectations to higher levels. To use these frameworks with your Rails app, you had a few options:
npm
or yarn
into the asset pipeline yourselfI have been using rails-assets.org the past few years to keep my JavaScript dependencies up to date. It thought it was smart solution; instead of requiring individual developers to maintain Gem-wrappers, Gem wrappers are created on the fly by RailsAssets.org. It was smart and light weight on the developers side and worked perfectly with the Rails' Asset p…
Just a small note that I've made some improvements to my SocialLinker-gem lately and while I've been using it on a few sites already, I wasn't using it on my very own blog. Today I found some time to change exactly that: you've got to eat your own dog food. If you want to have a taste of it: murb/social_linker (if you're a ruby-dev) or just click the share icons below :)
Image CC-licensed BY: Sh4rp_i
This is a short follow up on the previous article in which the ActionCable basics were explained. We can now add some level of authentication. Authentication is a bit harder than simply registering some before_action
’s, but it is perfectly doable, especially if you've survived the previous tutorial.
From the official Action Cable guide we can simply reuse the full connection.rb template:
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
protected
def find_verified_user
if current_user = User.find_by(id: cookies.signed[:user_id])
current_...
As the lead developer at HeerlijkZoeken.nl I wanted to try the new Rails ActionCable technology for a new feature: shopping lists. The idea is that you can walk in a store or on a market, mark an ingredient as checked when you add it to your (physical) basket and continue shopping. ActionCable can make the experience nicer because it, based on WebSockets, allows for real time notifying other viewers and editors of the same shopping list. No more shouting around in the supermarket: I’ve got the milk! Sure, nothing essential, but I needed an excuse ;)
(Note that we recently migrated from Rails 4, so not everything was in place in our app, just ignore the bits Rails already made for you; everything has been tested with Rails 5.0.0.1)
To start: You need a web server that can open multiple threads, so if you’re still using Webrick in development (which can’t rece…
murb bestaat 6 jaar. Een goed moment om terug te blikken op de opdrachten van weleer. Deze keer: QKunst Collectiebeheer
Dit is wat QKunst zelf schrijft:
> QKunst is gespecialiseerd in het inventariseren van grote bedrijfscollecties. Om deze inventarisaties nog soepeler te laten verlopen, ontwikkelden wij QKunst Collectiebeheer, een web applicatie voor collectiebeheer. Hiermee worden grote hoeveelheden informatie over een collectie toegankelijk en kunnen we uitgebreide rapportages uitdraaien.
QKunst had te maken met meerdere zaken die verbeterd konden worden ten opzichte van hun oude tool: Excel.
Gaandeweg ontonden er nieuwe ideeën waarmee de dienstverlening verder verbeterd kon worden: communica…
LinkedIn confronteerde me onlangs nog met het feit: murb bestaat alweer 6 jaar. Een goed moment om verder te gaan met terugblikken op de opdrachten van weleer.
De belangrijkste opdrachtgever in mijn beginjaren was de ING bank. Een belangrijk product dat ik in de begintijd aldaar heb gebouwd is een database op basis van Excel-bestanden (iets dat ik ooit nog wil(de) uitrollen als 'AxlBase'). Zoals ik eerder al schreef, soms moet je een bestaande werkwijze omarmen. Wat is het precies en van waaruit is het ontstaan?
Een database op basis van Excel-bestanden. Niet echt in technische zin (achterliggend is het een traditionele database), maar wel in de praktische zin. Excel is hét bestandsformaat van de gewone kantoormedewerker voor gestructureerde data. Het wordt veelvuldig gebruikt in allerlei projecten. AxlBase is in staat verschillende Excel-bestanden per o.a….
Dit artikel van murblog van Maarten Brouwers (murb) is in licentie gegeven volgens een Creative Commons Naamsvermelding 3.0 Nederland licentie .