My time with Rails is up (2016)
solnic.codes
solnic.codes
Laravel is the same way in PHP, IMO. I think that's a big reason people hate on Laravel so much.
That’s the point of Rails. That’s the point of any framework really— predetermined opinionated implementations of common functionality, so that you don’t have to build it. You’re going to have a bad time with any framework if you need control of the predetermined opinionated implementations.
I guess we should all stop complaining about linux, etc.
Just about everything he mentioned aren't particular to rails, it's just a natural consequence of decisions being made.
For example, he complains about the coupling between active record and the rest of the system. And he's not wrong, but the thing is, this happens with every ORM in existence, including data mapper style libraries. The reason for this is easy to understand, people sprinkle ORM code throughout their codebase instead of having a proper DAL (they treat the ORM as the DAL rather than a mechanism for fetching data).
Any ORM that you use where you sprinkle it directly through your entire codebase is going to experience tight coupling. And you can see it in a lot of ORM designs where the ORM itself will create mechanisms for "query re-use" and most of them are actively damaging to code maintenance.
I remember the first time I read the treatise on "Object-Relational Mapping is the Vietnam of Computer Science" and being surprised that people actually used ORM's that way.
I guess my point is that every decision made causes problems, sometimes those problems are obvious in the short term and sometimes they're not and they take longer to become obvious. This author sounds as if they fell in love with Ruby and have now worked with it long enough to start seeing the problems but they're blaming Rails when a lot of the issues are deeper than that. Rails may exacerbate it, but these problems are not unique to Rails.
And if I may, part of the churn we see in tech is due to people constantly looking for the perfect solution (non-problematic in any way). That's not engineering, any jackass can point out problems (theoretical or otherwise).
What I'm saying here is I think the author is maturing but they need to consider that maybe Rails shouldn't be the only tool in their toolbox.
The gift that keeps on giving.
The PHP part would run just fine but the Js tools broke the app. npm install never just works.
In my experience Compiled js apps decay really fast.
The more complex newer the build tool, the fast it decays.
Rails 7 finally came up with better solutions out of the box. My latest application uses esbuild and the javascript version of sass. All javascript and css libraries are handled by node packages. Way less pain.
However when you get to multiple teams and multiple 100s of kloc, the architectural demands start to get stronger, and Django can become a bit hard to work with. If you have a shallow wide domain, then it's not really a problem; just stick to fat models with controllers, and everything is OK, you just add more models. But when your domain is deep, with layers of concepts, and lots of interaction between different subsets of models, you start to want to pull out an Application Layer to wrap your Domain Layer.
Tactically it also starts to be really hard to guarantee you're not doing O(N) queries, and I've found django-seal to be a great solution (seal a QuerySet after fetching so you can't accidentally do follow-up queries, forcing you to build everything into a single query with select_related/prefetch_related). However when you look at how complex the implementation of the *_related caching is, you start to wonder if a simpler, more flexible ORM like SQLAlchemy would serve you better.
I think "how many loc is your app" would be a helpful qualifier for these discussions, as I suspect lots of people waving the "I love Rails" flag are writing smaller apps, and the "I won't use Rails again" are working on 1m loc projects. Right tool for the job, both opinions can be valid at the same time when qualified with "... for apps of size ~X".
What I find lacking in most MVC backend frameworks lack is the componentization and composition of business rules in and across individual models. dry-rb and trailblazer were good efforts in this direction, but the reality is most backend apps in production stay mired in low-level implementation effort and duplicated code with whatever the MVC framework provides.
Also, the presenter pattern tends to require a bolting on in most frameworks.
IG’s Django must be pretty weird since the ORM will be driving Tao/Ent, rather than a normal SQL database? I wonder what the code looks like.
SQLAlchemy is way more complex and does more stuff (more robust connection pooling for example). There are a lot more complex things you can do with prefetching related rows with SQLAlchemy (there’s like 5+ different ways to do it?).
You’ve actually used sql alchemy for a project? It’s great, I just wouldn’t describe it as simpler.
Maybe “less opinionated” is what I’m getting at; it has smaller, more composable building blocks and while the ORM API surface itself is in some sense more complex, it doesn’t have the kitchen sink of ActiveRecord integration that Django does. It seems to me that when you pick an implementation, you perhaps have a little more boilerplate than Django, and then the slice of the SQLAlchemy API you end up using is smaller and more explicit. So the app’s usage of the ORM ends up being simpler (even though you might have to write a little bit of framework code yourself).
(Yes, I’ve used both, Django more though.)
My good sir, you just wrote a very long hate letter about a tool.
This happens over and over again because it appears so alluring and friendly that it attracts newcomers like flies.
DSLs (looking at you, Kotlin flavoured Gradle), magic annotations (Spring Boot) and ORM frameworks are great in theory, but pray shit doesn't hit the fan, because then you're off debugging the intricate internals of said leaky abstractions.
I suspect it was part of the reasons Scala died, and while I can't say I love Golang, they seem to be only ones with a culture that actively discourages this.
The "convention over configuration" kind of sucks since it's far too easy to break from "convention".
Scala is quite inspect-able, you can always use static analysis tools and IDE to find how everything works. Usually just one cmd+click away. Even metaprogramming, although can be hard to understand – its easy to search for. If you are referring to 'Dynamic' (call methods which do not exist during compile time), to be honest, its extremely rarely used in code.
Good luck figuring what's happening in Ruby metaprogramming where you don't know what to search.
I read somewhere in linkedin: Scala is dead because average developer is sad. I think there might be some truth to that statement. In my experience, Scala works wonderfully with motivated engineers
The "Scala works wonderfully with motivated engineers" is basically damning with faint praise. "Smart languages" always work well with single high IQ engineers, the litmus test is does it work in a team of engineers with varying talents, which is simply how the real world works. Even if everyone is above average, those types of engineers are often very opinionated and prefer different slices of the cake, which results is social friction and incidental complexity. The C++ guys know exactly what that is like.
I've built several apps with Rails years ago that are still running on the web. Is Rails something I should look at using again, or are there other choices that would be better to look at? If so, which ones? I'm more familiar with Ruby than I am with PHP or Python.
The biggest counter point I have with those articles criticizing Rails for being "too magical" is to ask: what is the alternative?
And I don't mean alternative in a sense that one developer will do something by hand. More like: what would you suggest a "medium-xxl" app company (author's words) do?
Use another framework? Fair.
But, as others have said, it is 2023 and even still most other frameworks still won't come close to Rails. Laravel is pretty close, Django as well. Next? I still miss Rails from 2009 (when I started learning it) when dealing with Next every day.
Build some custom solution? Fair as well.
But, how do you enforce standards over a big team? I used to work with Rails, then I went to work in a Flask app with multiple teams working on it...
What happens in practice is, without a strong framework like Rails, each developer/team ends up creating its own little framework, with its own little quirks and ways to do thingz. And then when you need to maintain it, you need to learn a whole "new" ad-hoc framework, most of the times with no documentation and without the original developer to explain it to you. And the differences between what different teams/developers come up with can be drastic, completely different ways to do things.
Rails is not perfect, but having worked with the alternatives for years now, I still think Rails got way, way more things right then wrong. I'm starting a side project now with Remix, Prisma and almost every day I still fondly remember how Rails had all of this setup figured out way back in 2009 when I started working with it.
Almost any other framework/solution suggested, as the author said, for "medium-xxl" projects will have the same issues or even worse.
To this day, almost every week I get myself thinking that I still wish there was a "Rails for JavaScript" (since I need to work with JavaScript).
My time with Rails is up - https://news.ycombinator.com/item?id=11749203 - May 2016 (438 comments)
My biggest concern is that when your project deviates from the happy path of that functionality you've got to invent your own architecture and patterns. Knowing when to create a service objects vs say adding more functionality to a model is an example. In that case, you're out of the land of convention and into the land of opinion.
- Plain Old Ruby (The original.)
- Rails (Ruby++)
- Functional Programming (dry-rb and friends)
I find it really hard to sympathize with the functional programming crowd. They are trying really hard to make Ruby into something it isn't suited for. They committing many of the same "sins" as ActiveSupport by creating a large superset of the language. (Only bolted on instead of integrated.) The end result is having an awkward interface between their code and everyone else's. Similar to how jRuby feels.
What they really want is a different programming language with a ruby-like syntax with a massive standard library and many third-party libraries.
Trying to bolt paradigms from stricter languages onto Ruby is like nailing jelly to a wall.
Not saying this paradigm fits in Ruby, but it certainly works with discipline as well.
As for shoehorning things into Ruby – I think its fine to experiment. Libraries can always try to bring best practices from other languages, some might fit wonderfully, others might not. I personally dislike exceptions, I will happily include "fake" Result/Either for non panic workflows
Thank-you. Any word on the book he has been working on? Last post was February 2022.
That being said, I really cannot stand how abstracted certain parts of Rails are. This is further complicated by gems that may or may not follow convention and that Rails is not a strongly typed language. It can become nearly impossible to find documentation or worse documentation with completely missing components.
----
Example: Rails Migrations.
I love the Rails Migration setup. Once you write a migration, things just work.
However, writing an actual migration is an adventure at times.
* The documentation is sub-par with only the most basic examples in place.
* Advanced features are essentially undocumented. Did you know there's an Postgres specific migration guide? Good luck finding that from within the documentation.
* Much of the documentation ends you up in apidock where you learn critical APIs are completely undocumented.
* Terrible mix of named and unnamed parameters, some of them just seem like magic. Worse is the mixed use of things like types:
* t.column :identifier, :uuid (does this actually work? Seems like it should?)
* t.uuid :identifier (woah, where'd that magical function come from)
* t.references :foo, type: :uuid (woah, why does uuid require a named parameter here)
* Flags and options are poorly documented and it's often unclear what functions are (1) exposed from the database (2) abstracted away. * Did you know you can utilize the postgres comment field in migrations?
* Where do I use plural? Where do I use singular? Where does it get automatically converted? Why do I need plural here and singular there? Why can't everything simply use plural?* Do I need to use `required: false` or `optional: true` on this field? Why is that different than that other field?
These types of problems are all over the place. Far too many things seem to rely on stumbling on a random, likely outdated StackOverflow post. Many of these things would be far, far easier to understand with just a touch of verbosity and a bit less magic. That being said, when you do figure things out, the solutions are often short, elegant, and robust.
Recently, I've been finding ChatGPT incredibly helpful for wading through this cruft. It does really well with the advanced features. Even if it's slightly wrong, it gets me close enough without having to wade through documentation.
I've been using it with drizzle-orm[1] and it's been ok.
I still miss all the other stuff you get from Rails out of the box, but it's more complete than just Next.js without all the React acrobatics.
[0] - https://kit.svelte.dev/
Django tends to organize code by feature - signup, shopping cart, billing, profile, etc.
I've seen it explained as "Component Slicing" vs "Feature Slicing" - the term has appeared when I've looked into how to organize code in React projects but it fits.
It seems there are just different ways people model things in their mind and for some folks the Rails way works best, and for other folks the Django way works better.