Having worked on a lot of Rails codebases and teams, big and small, I think this article is pretty spot on. Once your codebase or team is big enough that you find yourself getting surprised by things like
counters = %i(one two three four five)
counters.each do |counter|
define_method("do_#{counter}_things") do |*args|
# whatever horrible things happen here
end
end
It’s gruesome, and I’ve seen a version of it (using define_method in a loop interpolating symbols into strings for completely ungreppable results) in at least 3 different large old codebases, where “large” is “50KLOC+” and “old” is “5+ years production”
There are a lot of ways to write unmaintainable code in a lot of languages/frameworks, but if I ever were to take a Rails job again, I would specifically ask to grep the codebase for define_method and look for this prior to taking the job. It’s such a smell.
I don’t understand why it’s so normalized in rails to define methods in the fly. You could do that monstrosity easily in most interpreted languages, but there’s a reason people don’t! On Rails, it’s just normal.
It’s been a long time since I’ve read the ActiveRecord source so it may no longer be this way, but there was a lot of this style of metaprogramming in the early versions (Rails 1.x and 2.x) of the Rails source, ActiveRecord in particular, and I think it influenced a lot of the early adopters and sort of became idiomatic.
The time between “just discovered ruby lets you do that” and “just realized why I shouldn’t” varies from person to person; I’ve seen it last anywhere between a week and a year.
This is a solid summary of things I have thought much about, and done a less-thorough job of explaining many times over the years. I look forward to its eventual final publishing, and will share with some colleagues then!
A somewhat-related topic I have thought about off-and-on: When you see “Rails advice” online, it tends to be coming from one of two very different contexts: product companies with entirely in-house engineering, managing their handful of projects, and consultancies who manage many, many projects. This adds a light bias towards/against whether Rails’ components parts are used idiomatically, whether you should deviate and apply “Objects on Rails”-like principles, and how far you can/should go with that.
I think all of that advice is ultimately good advice, but it is rarely self-conscious enough about having that specific lens. Maybe it’s implied if you’re a regular reader of the blog, but I think people would be well-served to keep that in mind and work out (for any given advice piece) which context the author is coming from (not limited to the two I listed), whether that is the same situation they are in, and how that impacts the advice.
Of course when I think about it, there is that famous curve where you have a huge uptick in a lot of coverage of a thing, with relatively few users in the grand scheme of things (but it appears like everyone is using it depending on what news bubble you are in). That been quite a few years ago now, so it is probably fair to say that Rails is quite mature at this point.
The only thing I don’t know: this the mature phase where usage increases slowly, or where usage decreases such that it eventually disappears?
As an aside, with the link to the Rails Doctrine I find it interesting to note when it talks about “Rails Migration of 2.x to 3” being painful, leaving a lot of people behind, and souring of others - it has a version number inline with python…
This article should be written for every framework or library :-).
It really depends on how much programming work is going to be required. If you’re planning to spend 6 weeks building and 6 years operating a site, rails doesn’t really make sense. If you expect to continually have multiple programmers work on the site, the operational overhead is negligible compared to the productivity advantages.
I’m honestly unclear which direction you think it’s strong in (I have heard much stronger opinions in both directions).
For context, I have used rails for paid work during every calendar year since 2008, though some years only had a little bit of it. In that time, I’ve held various roles including the primary on-call, lead developer, devops setup person, and also run several sites using various tech stacks.
Rails sites require a very different level of devops work to, say, golang. It’s typical for a rails app to require:
Multiple server roles (web, worker, periodic task trigger)
Multiple key/value stores (redis for sidekiq, memcached for caching)
A full webpack configuration
A relational database
Multiple third party APIs which don’t come with backoff configured (eg mailer, captcha)
You can have Graphql as an endpoint in an application without using it for everything.
on Rails you usually add graphql as another controller, that renders a Graphql Schema.
That said — I really don’t like how GraphQL works in Rails, so in a well designed system it probably should be mutually exclusive.
Having worked on a lot of Rails codebases and teams, big and small, I think this article is pretty spot on. Once your codebase or team is big enough that you find yourself getting surprised by things like
etc… you’ve outgrown rails.
This is my litmus test for “has this person had to maintain code they wrote years ago”.
I don’t think I’ve yet worked with anyone who can answer yes but also wants me to maintain code that can’t be found via grep.
What unholy beast is that. I mean. Seriously. Wtf is that?
It’s gruesome, and I’ve seen a version of it (using
define_method
in a loop interpolating symbols into strings for completely ungreppable results) in at least 3 different large old codebases, where “large” is “50KLOC+” and “old” is “5+ years production”There are a lot of ways to write unmaintainable code in a lot of languages/frameworks, but if I ever were to take a Rails job again, I would specifically ask to grep the codebase for
define_method
and look for this prior to taking the job. It’s such a smell.I don’t understand why it’s so normalized in rails to define methods in the fly. You could do that monstrosity easily in most interpreted languages, but there’s a reason people don’t! On Rails, it’s just normal.
It’s been a long time since I’ve read the ActiveRecord source so it may no longer be this way, but there was a lot of this style of metaprogramming in the early versions (Rails 1.x and 2.x) of the Rails source, ActiveRecord in particular, and I think it influenced a lot of the early adopters and sort of became idiomatic.
Who the fuck writes code like this?
shudders
The time between “just discovered ruby lets you do that” and “just realized why I shouldn’t” varies from person to person; I’ve seen it last anywhere between a week and a year.
This is a solid summary of things I have thought much about, and done a less-thorough job of explaining many times over the years. I look forward to its eventual final publishing, and will share with some colleagues then!
A somewhat-related topic I have thought about off-and-on: When you see “Rails advice” online, it tends to be coming from one of two very different contexts: product companies with entirely in-house engineering, managing their handful of projects, and consultancies who manage many, many projects. This adds a light bias towards/against whether Rails’ components parts are used idiomatically, whether you should deviate and apply “Objects on Rails”-like principles, and how far you can/should go with that.
I think all of that advice is ultimately good advice, but it is rarely self-conscious enough about having that specific lens. Maybe it’s implied if you’re a regular reader of the blog, but I think people would be well-served to keep that in mind and work out (for any given advice piece) which context the author is coming from (not limited to the two I listed), whether that is the same situation they are in, and how that impacts the advice.
My first thought is: People still use Rails?
Of course when I think about it, there is that famous curve where you have a huge uptick in a lot of coverage of a thing, with relatively few users in the grand scheme of things (but it appears like everyone is using it depending on what news bubble you are in). That been quite a few years ago now, so it is probably fair to say that Rails is quite mature at this point.
The only thing I don’t know: this the mature phase where usage increases slowly, or where usage decreases such that it eventually disappears?
As an aside, with the link to the Rails Doctrine I find it interesting to note when it talks about “Rails Migration of 2.x to 3” being painful, leaving a lot of people behind, and souring of others - it has a version number inline with python…
This article should be written for every framework or library :-).
Notably, this site is written in Rails.
That is interesting actually. I wouldn’t have excepted that.
I’m still finding rails astonishingly productive if your team can handle the (significant!) ops overhead.
So many little details that work well.
That is probably one of the things that kept me from ever bothering with it TBH. I find stuff like asp.net more straightforward.
It really depends on how much programming work is going to be required. If you’re planning to spend 6 weeks building and 6 years operating a site, rails doesn’t really make sense. If you expect to continually have multiple programmers work on the site, the operational overhead is negligible compared to the productivity advantages.
That’s a very strong claim to make.
Maybe in 2005 when RoR was considered cutting edge. But today?
I’m honestly unclear which direction you think it’s strong in (I have heard much stronger opinions in both directions).
For context, I have used rails for paid work during every calendar year since 2008, though some years only had a little bit of it. In that time, I’ve held various roles including the primary on-call, lead developer, devops setup person, and also run several sites using various tech stacks.
Rails sites require a very different level of devops work to, say, golang. It’s typical for a rails app to require:
I’d add don’t use rails if you’re not developing a REST based API, rails graphql support is a Frankenstein.
Aren’t REST and graphql mutually exclusive?
You can have Graphql as an endpoint in an application without using it for everything. on Rails you usually add graphql as another controller, that renders a Graphql Schema.
That said — I really don’t like how GraphQL works in Rails, so in a well designed system it probably should be mutually exclusive.