Hacker News new | past | comments | ask | show | jobs | submit login
My time with Rails is up (2016) (solnic.codes)
39 points by Palmik on Sept 12, 2023 | hide | past | favorite | 47 comments



Overwritten article complaining about mature framework the author admits he didn’t even attempt to contribute to. I’ve loved Rails since 2008. Perfect? No. Wonderful? Yes.


Admittedly I couldn’t make it through the whole article, but what I did read came across as “don’t other people KNOW that the components are TIGHTLY COUPLED?! There is MAGIC happening and it’s bad don’t you SEE!!”

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.


This is why I no longer blog. Guy puts time into a blog post writing his thoughts only to be told it's overwritten and he's complaining about something he didn't even try to contribute to.

I guess we should all stop complaining about linux, etc.


Yeah, but this is just rails folks bristling at someone calling their baby ugly. People like to pretend that it's just technology, but there's always personal, emotional investment in the choice, which leads to a need to defend it against perceived attacks.


yeah, I think he's just maturing as a developer and rails was his first love.

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.


Rails is great for building something fast with great tooling. Twitter started with Rails, IIRC, and eventually migrated to Scala. That's okay, that's what you do as you grow and see it cannot do what you need it to do.

Laravel is the same way in PHP, IMO. I think that's a big reason people hate on Laravel so much.


Interesting. My own biggest gripe with rails is, by far and large, that any project that even so much as lightly touched the js ecosystem will become unbuildable within about 2 months if you don't tweak things. And for Rails, a huge driver of this is the sass compiler, which (afaict) will download a hosted binary component for recent enough versions but will fall back to building it if it's too old. And "too old" appears to be measured in months. But it's far from the only thing that breaks it.


Rails 6 was a nightmare with javascript. Continuing down the path of handling javascript and css dependencies with ruby gems was a mistake.

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.


Rapid ecosystem churn is my gripe with Javascript. I've generally found Rails and popular Ruby gems to be very durable over time.


Ruby and Javascript are interpreted languages! Why does there even need to be a build step?


My issue with Rails has always been that-- not just the JS ecosystem rot, but gems in general. Running "bundle update" after six-eight months is like rolling the dice. Especially if you use any Rails engines, etc.


What expires within 2 months?


Not just with rails, laravel had this problem with js/ mix.

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.


JavaScript


Oh, that :(

The gift that keeps on giving.


I see some of the same problems in Django; it's so productive at first, the ecosystem is great, DevX is delightful, and when your app is simple enough that a layered architecture feels like way too much boilerplate, you can just write amazing simple code. A great example is Simon Wilson's recent post https://til.simonwillison.net/django/building-a-blog-in-djan... - the views.py is :chefs-kiss:.

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".


“simpler, more flexible ORM like SQLAlchemy would serve you better”

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.


Yeah perhaps “simple” isn’t the right way of putting it, the learning curve is way worse.

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.)


Instagram's backend is (mostly) a single, giant Django app. So it is possible to put together massive apps in it. I didn't have the time to delve into the architecture.

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.


It’s certainly possible, but is it a good idea? Would be interested in general sentiment from those working in that codebase. (Though FB uses Hack so I think there is a general tendency at Meta to scale whatever happens to have been used to build the first version, rather than decompose and rewrite some pieces.)

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.


they ditched orm in favor of own implementation years ago


> We’re discussing a tool, not a person, no need to get emotional

My good sir, you just wrote a very long hate letter about a tool.


> People are attracted by Rails because it gives you a false sense of simplicity, whereas what really happens is that complexity is being hidden by convenient interfaces.

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.


>I suspect it was part of the reasons Scala died

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 same is true about Gradle's Kotlin DSL, and it is hard to understand what exactly is happening under the hood and what the correct way to invoke things really is. With Scala this problem is even more pronounced, because its type system is more powerful, so you can build even more intractable abstractions.

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 love Rails, but the author's complaint is also my most frequent complaint.

The "convention over configuration" kind of sucks since it's far too easy to break from "convention".


I'm not sure "convention over configuration" is in itself a problem. Opinionated defaults and patterns don't have to lead to incomprehensible abstractions, but I guess it takes some restraints.


I have a simple-ish webapp to write that involves basic CRUD, hookup to the Stripe API for payment, a hookup to Twilio for SMS texting, some kind of cool image gallery display UI and well that's about it.

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.


I think it's neat reading people comment here that don't know who piotr solnica is. He's not some ruby schlub that is unfamiliar with the tradeoffs he was discussing


I read the whole article, and I think there are good points and things I disagree with.

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).



Thanks! Macroexpanded:

My time with Rails is up - https://news.ycombinator.com/item?id=11749203 - May 2016 (438 comments)


On balance, I like Rails because you get so much functionality out of the box.

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.


Sigh. There are three major camps with Ruby.

- 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.


The weirdest thing about things like dry-monad is that they're so incredibly shoehorned in. In places like Haskell, the default for a function is to be pure and monads add some capability for side effects (ie logging, or keeping state, or error tracking, all the way up to arbitrary IO). In Ruby on the other hand, the default is that a method can do anything it pleases, from from monkeypatching the standard libraries to database queries to launching intercontinental nuclear missiles. There is (by design!) no contract enforced at all on what the code can do.

Trying to bolt paradigms from stricter languages onto Ruby is like nailing jelly to a wall.


FP Scala is enforced by discipline rather than the language itself. It works wonderfully, even though you don't have effect tracking and can launch intercontinental missiles everywhere.

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


FYI: the author of this article is one of the creators of dry-rb.


And he's still as bitter about Rails now as he was in 2016. :)


> ... I care about Ruby’s future. The reason why I decided to write a book is that explaining all the new concepts we’ve introduced in various libraries is close-to-impossible without a book.

Thank-you. Any word on the book he has been working on? Last post was February 2022.


The guy was still blogging about rails last year, so it seems the time with rails wasn't really ended after all. It would be nice with a follow-up post.


7 years old and still the go-to article I cite when I want to explain why I no longer work with Rails.


I've tried out a bunch of different tools on side projects, but always find myself coming back to Rails. It simply does so much out of the box and it does it in a way that generally plays nice with the entire framework. Every other set of tooling I've used, I quickly run into problems that Rails solves out of the box. I either need to spend hours configuring a bunch of components, rework things after discovering a breakage, or write insane amounts of boilerplate code.

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 NodeJS and Next.js stacks lately and man how i miss Rails


Try Sveltekit[0] it's a lot more like the VC part of Rails' MVC style.

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/

[1] - https://orm.drizzle.team/docs/overview


I never understood the appeal of rails when django was available, and used python which many more people already know/knew.


Rails projects generally organize code around what type of class you're writing (generally, a Model, a View, or a Controller (Mailers, Workers, Services, Helpers are less frequently used)).

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.


Ah, thanks very much! I hadn't realized that was a difference.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: