murb ♥︎ ruby

It may not be the fastest programming language, nor is it the most popular language when it comes to the numbers game, but how can you not fall in love with:

 10.times { print "Hello!" }

(instead of something like for(var i=0; i<10; i++){ console.log("Hello!"); })

Do things with sets like:

["a", "b", "c"] & ["b", "c", "d"] # gives you ["b", "c"]
[1,2,3] + [4,5] # gives you [1,2,3,4,5]
["a", "b", "c"] - ["b", "c", "d"] # gives you ["a"]

Or (with a little (opinions differ on this one ;)) help of Rails):

10.days.ago

That offers you exactly what you would think it would return: the date of 10 days ago.

And no ;’s, only brackets when absolutely needed, everything is an object…

Yes, it’s actually a language a human might understand, and still: it is pretty powerful, powering some of the most popular sites on the web, like AirBnB, Shopify, Basecamp (they’re the creators of Ruby on Rails), Github, Kickstarter, Twitch, Strava and many more (most of the full stack projects I did & do are using ruby).

I'm nitpicking a bit on code naming...

An article, posted 10 days ago filed in ruby, development, software, naming & Martin Fowler.

Today's review had a final note: I'm nitpicking a bit on code naming. The approaches you take are good, but naming is hard:

> There are only two hard things in Computer Science: cache invalidation and naming things.

(see here a list of variations on these two hard problem 'jokes' in Computer Science)

I enjoy the ruby programming language because you can get a long way just assuming things. They might say, never assume things, because a lot of things are chaos, but I prefer to work from assuming things, and if it doesn't match to my assumption choose:

  1. fixing the assumption (perhaps by making the method name more clear)
  2. make it so that what I assumed to be working works (and I never ever have to think about or bother by it anymore)

… and/or maybe, I am just wrong and I should level up my understanding of things. We all have our internal models of how things work, some…

Continue reading...

(Database) Transactions should be used modestly

An article, posted 3 months ago filed in database, sql, programming, ruby, performance & simplicity.

It is good practice to leave your database in a consistent state. There are different ways to do this. Foreign key constraints, indexes, typing of columns, are all strategies to keep your database in a consistent state. Transactions are another way providing you a tool to keep the database consistent: if one of the inserts or updates fail, your database will rollback to the state before the first in the series of inserts and updates within that transaction.

Some languages make it really simple to create a transaction. In Ruby on Rails it is simply opening a block:

User.transaction do
  ## ... all db operations are now in a transaction
end

But be cautious; transactions don't come for free: they lock the table or row, which is bad for performance. It can, by design, stop other processes from updating the same rows. And all this gets worse when transactions take longer, when for example they contain request to remote resources.

Hence, my approach to transact…

Continue reading...

Generating and parsing data URI's in Ruby

An article, posted 3 months ago filed in uri, data, url, data-url, ruby, link, browser, html, json & api.

I'm fond of data-URI's (MDN Link). 12 years ago I reappropriated a tool that stored a webpage with its related resources in a Microsoft specific format and rewrote it into something that would store it in normal HTML where the related resources were encoded in data URI's. Recently the topic came up again at a project I was working in, where microservices are still a thing. And while discussing it with colleagues it seemed as if knowledge about this quite useful URI-scheme wasn't on top of everyone else's mind. Instead, the original idea was, we could upload the resource to S3, pass the link, download the resource from S3 at the receiving end, and then have some policy that takes care of deleting it… nah…

data-URI: The basics

This is the most simple data-URI:

data:,Hello%2C%20World%21

You [can open it in your browser](dat…

Continue reading...

When to use decorators

An article, posted 5 months ago filed in ruby, rails, ruby on rails, service, architecture, when to use & models.

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.

Continue reading...

I love you ruby, `unless`...

An article, posted 5 months ago filed in sorting, ruby & programming.

I'm quite familiar with writing ruby code. I've even expressed my love for the language long time ago. But some constructs still bug me. One of them is unless…

I've seen variants of this code:

temperature = 36.7
unless temperature &gt; 37.2 || temperature  35.5 &amp;&amp; temperature &lt; 37.2
  puts &quot;Healthy temperature. Temperature is within the normal range.&quot;
end

or perhaps even nicer:

if (35.5...37.2).include?
  puts &quot;Healthy temperature. Temperature is within the normal range.&quot;
end

Continue reading...

Sorting text

An article, posted 7 months ago filed in sorting, ruby, programming, database, order, databases & sql.

There are a few hard problems in computing. Correctly handling time, naming, preventing off by one errors… sorting text may not be one of them but recently we ran into a discussion where I couldn't make up my mind anymore. Hence, this post's topic: sorting text.

The problem

How do you sort the following words:

  • cheese
  • Ape
  • Drums
  • dent
  • Beer

If you'd ask ruby I'd get:

 %w[cheese Ape Drums dent Beer].sort

Results in:

  1. Ape
  2. Beer
  3. Drums
  4. cheese
  5. dent

Which in my useless and ramshackle programmer's brain translates to, well why not, it is sorted right?

But then we moved the data into a database which was correctly set up with a proper locale for 'collation', a term that I've seen but never meant anything to me until this problem. Collation is:

> the assembly of written information into a standard order.

(thanks Wikipedia - Collation)

Databas…

Continue reading...

When to use x-objects?

An article, posted 12 months ago filed in ruby, rails, ruby on rails, service, architecture & when to use.

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:

Presentation

  • Controllers (standard Rails)
  • Channels (standard Rails)
  • Views (standard Rails)
  • Presenters
  • Form Objects
  • Filter Objects

Application

  • Authorization Policies
  • Jobs (standard Rails)
  • Event listeners
  • Interactors
  • Deliveries
  • Notifiers
  • Mailers (s…

Continue reading...

When to use Modules / Concerns?

An article, posted about one year ago filed in ruby, rails, ruby on rails, service, architecture, when to use & modules.

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.

Concerns or Modules?

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…

Continue reading...

When to use Form-objects?

An article, posted about one year ago filed in ruby, rails, ruby on rails, service, architecture, when to use, async, form & models.

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.

Continue reading...

When to use Job (or Worker) objects?

An article, posted about one year ago filed in ruby, rails, ruby on rails, service, architecture, when to use & async.

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.

Continue reading...

Tag descriptor

When to use...

An article, posted about one year ago filed in ruby.

I've got some opinions about certain ways of setting up more advanced (mostly Rails) applications. These might be short 'posts' which I might return to later. Let's see how it goes :)

Continue reading...

When to use Service-objects?

An article, posted about one year ago filed in ruby, rails, ruby on rails, service, architecture & when to use.

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.

Continue reading...

Tag descriptor

pupprb

An article, posted almost 2 years ago filed in rubygems, ruby & gem.

pupprb is a simple wrapper around puppeteer, a tool maintained by Google Chrome engineers, which I primarily use to print PDFs. This gem simply wraps my default settings / approach in a relatively easy to reuse gem.

Source: @gitlab Rubygems: pupprb

Continue reading...

Tag descriptor

CentralLogin

An article, posted almost 3 years ago filed in ruby, CentralLogin, gem, rubygem, murb, authorization, authentication, roles, groups, resources, open source, mit, openid & oauth.

A simple OAuth provider. See below for more information, or check out the source of CentralLogin on GitLab. To integrate it with your ruby-apps, use the omniauth-central_login gem.

Continue reading...

Introducing CentralLogin, an OpenID Connect Provider

An article, posted almost 3 years ago filed in ruby, CentralLogin, gem, rubygem, murb, authorization, authentication, roles, groups, resources, open source, mit & oauth.

This app builds on the foundations of the Doorkeeper, Doorkeeper::OpenidConnect and Devise to provide a central login system.

While Doorkeeper supports other OAuth flows, CentralLogin focusses on OpenID Connect as it is a more complete, and hence useful standard, for most use cases where you want to support authentication & authorization.

This project builds on years of juggling with different authentication providers and implementations. It may cut corners to be a pragmatic and less flexible solution which you can host on your own. You don't have to tie your users to a closed authentication system such as Auth0, Azure Directory, Cognito (the horror, really, stay away from it) or something else. In the past I've been a happy user of Keycloak, which is definitely way more advanced than this project, but it in the end it is a Java application and hence harder for me to maintain and not focussed on what I think are the core requirements :)

So, are you in the market for:

  • a…

Continue reading...

murb blog