News for hackers. Stuff that matters.
Re:Rewrite it in Rails by wkirby on Monday November 04, 2024 @12:31PM (#42043898)
I spend a lot of time each year evaluating frameworks for our clients and their projects, and I keep on coming back to rails.

> Does it turn into unmaintainable spaghetti code after a while? Only if you let it. It's typically caused by developers, not programming languages or frameworks.

After running a number of rails applications in production for going on a decade, this is really hard, and I find it to be one place where rails (really ruby) doesn't help much.

Of all the languages we work in (and it's quite a few), ruby has the worst support for modern language tools: the LSP implementations are weak, and don't play well with containerized development environments. Typing efforts are fractured, and the official way is... well.. it's bad. This is exacerbated by ruby's tendencies towards "fluent" interfaces, which is actually code for lots of methods that take undocumented hashes of arguments --- and hash access with strings and symbols? nightmare fuel.

But I still come back to rails. It's productive, it's fast enough, it scales just fine, and perhaps most importantly there's a "right" way to do just about everything your web application will ever need to do: background jobs, websockets, read-only database replicas.

All in all, its still my recommendation for new web projects going into 2025.

Re:Rewrite it in Rails by runjake on Monday November 04, 2024 @01:14PM (#42044411)
> Does it turn into unmaintainable spaghetti code after a while?

I say this genuinely enjoying JavaScript programming, but my mind immediately jumped to "as opposed to immediately, like most JS frameworks?"

Re:Rewrite it in Rails by wkirby on Monday November 04, 2024 @04:55PM (#42046377)
I do find 6-month old typescript to be easier to return to than 6-month old ruby — same goes for most typed languages. The reality is, though, that the benefit of strong types isn't so much in giving you compile time errors as it is forcing the devs to document their method signatures.
Re:Rewrite it in Rails by chris12321 on Monday November 04, 2024 @07:07PM (#42047422)
I find that a 6-month-old JS project will often not even boot since its exhaustive dependency list will be out of date and now mutually incompatible. You have to feed a JS project with updates every couple of hours, or it will die like a Tamagotchi.
Re:Rewrite it in Rails by shepherdjerred on Monday November 04, 2024 @10:04PM (#42048240)
I've seen comments like this almost daily this week.

Does HN not use lockfiles or something? Your node/npm project will work just fine if you use the same version of node/npm and have a lockfile.

Maybe you're using npm i (which can upgrade dependencies in some cases) instead of npm ci [0] (which always uses the lockfile dependencies).

In any case, this is a general problem of package managers and has nothing to do with the language. You'll need something similar if you're using _any_ external dependency in Rust, Python, Go, etc.

[0]: https://docs.npmjs.com/cli/v10/commands/npm-ci

Re:Rewrite it in Rails by sodapopcan on Monday November 04, 2024 @12:56PM (#42044211)
> and perhaps most importantly there's a "right" way to do just about everything your web application will ever need to do

A good chunk of chaos in Rails apps is caused by people who either insist they know better than the out-of-the-box solutions, or they “just prefer it my way.”

Re:Rewrite it in Rails by cpursley on Monday November 04, 2024 @01:00PM (#42044251)
The biggest issues in Rails come from trying to do things with the ORM that should be done in the database.
Re:Rewrite it in Rails by PittleyDunkin on Monday November 04, 2024 @01:20PM (#42044480)
Even as a bonafide activerecord hater, this sentiment doesn't make much sense to me. The ORM is like 70% of what makes rails fast to develop with, which is the entire reason to use rails in the first place. Everything from routes to rendering to form validation is tightly integrated around object lifecycles. If you get rid of that there's not much benefit to use rails (or in fact ruby) at all.
Re:Rewrite it in Rails by randomdata on Monday November 04, 2024 @02:12PM (#42045005)
Wouldn't you say you are a bonafide activerecord hater because of those same issues? I don't expect you hate it because your lost love interest shares the AR initials.

ActiveRecord can both offer fast development and create issues (especially those that only come to bite you later). It exists in a multi-faceted environment. Tradeoffs, as always.

Re:Rewrite it in Rails by PittleyDunkin on Monday November 04, 2024 @02:42PM (#42045310)
Yes, I think it generally makes rails much more difficult to scale than it has to be, much more difficult to test, and more difficult to verify changes are "safe". I certainly agree with the commentary on tradeoffs, though, and I stand by my comment that AR is a big part of why Rails is such a massive success.
Re:Rewrite it in Rails by randomdata on Monday November 04, 2024 @02:45PM (#42045337)
> I stand by my comment that AR is a big part of why Rails is such a massive success.

I think most would agree. It is the "doesn't make much sense" part that we're discussing, though. How does it not make sense when you seem to have the same opinion of it? It seems, as an onlooker, that it makes perfect sense to you.

Re:Rewrite it in Rails by PittleyDunkin on Monday November 04, 2024 @03:12PM (#42045566)
> How does it not make sense when you seem to have the same opinion of it?

Well, what remains of Rails or of ActiveRecord once you remove the part that's done outside the database? It just seemed like a very shallow view of what rails is.

Re:Rewrite it in Rails by randomdata on Monday November 04, 2024 @03:19PM (#42045626)
Does anything need to remain? That is where my confusion lies.
Re:Rewrite it in Rails by cpursley on Monday November 04, 2024 @05:18PM (#42046583)
This entire response thread looks like the classic AR N+1 problem ;)
Re:Rewrite it in Rails by randomdata on Monday November 04, 2024 @09:43PM (#42048148)
Because of the high latency between messages? After all, eliminate the latency and the N+1 problem goes away.
Re:Rewrite it in Rails by cpursley on Wednesday November 06, 2024 @06:48AM (#42060593)
Why not just use the database correctly?
Re:Rewrite it in Rails by randomdata on Wednesday November 06, 2024 @12:23PM (#42065711)
What do you mean? The N+1 problem lies on the theoretically correct solution. That is using the database properly.

It is just not tenable where latency poses a practical constraint under an implementation that is not theoretically sound. There are plenty of hacks to work around it, though, so it is not really a problem in practice. To call those hacks to work around a system with shortcomings "using the database properly" is a bit of a stretch, though.

Just so we're clear, the use of JOIN, IN, etc. are not hacks in and of themselves. They serve a purpose even where latency doesn't exist. But when applied to solving the N+1 problem, their use is a hack. Again, one that gets the job done and solves the problem – hacks aren't bad, but is not theoretically sound. If you did not have latency constraints to contend with, you would not prefer it.

The better question is: Why use a database that sucks? Latency periods are small enough in SQLite, for example, that you don't have to worry about the N+1 problem in any real-world situation. It doesn't have to be a problem in need of hacks.

Re:Rewrite it in Rails by rco8786 on Monday November 04, 2024 @02:06PM (#42044961)
I think historically that's probably right, but something that has gotten much better with time.

Previously, ActiveRecord gave newer programmers a legible, fluent interface to the database in a language they already knew. So instead of learning SQL, we abused the heck out of AR. I think that the industry, and rails itself, has matured since then and I see a lot less of this nowadays.

Re:Rewrite it in Rails by mehal on Monday November 04, 2024 @01:05PM (#42044311)
Strongly agree to this. Rails developers for some reason just abandoning any work in database and tend to work with data in ruby env
Re:Rewrite it in Rails by cpursley on Monday November 04, 2024 @05:20PM (#42046600)
Yep, I'm a big fan of building views in postgres and just hitting those with the ORM. I don't even use the join syntax in my ORM (Ecto) - if I need a join, I use a view.
Re:Rewrite it in Rails by arcanemachiner on Monday November 04, 2024 @06:20PM (#42047088)
Interesting. Does Ecto have any syntax that supports this behavior? Or do you just use raw SQL for this?
Re:Rewrite it in Rails by cpursley on Monday November 04, 2024 @07:53PM (#42047658)
You just treat a view the same way as a table with Ecto.
Re:Rewrite it in Rails by PittleyDunkin on Monday November 04, 2024 @01:18PM (#42044456)
the extensive use of method_missing doesn't help either.
Re:Rewrite it in Rails by rco8786 on Monday November 04, 2024 @02:07PM (#42044963)
That's been gone since Rails 4 or 5 (we're on 8 now)
Re:Rewrite it in Rails by semiquaver on Monday November 04, 2024 @01:36PM (#42044658)
Can you point to any substantial places in rails where method_missing is actually used? The only place I’m aware of is dynamic finder methods like find_by_foo, which IIRC were removed years ago. Most of the more magical ORM stuff is implemented using boot-time metaprogramming things like define_method.
Re:Rewrite it in Rails by PittleyDunkin on Monday November 04, 2024 @02:01PM (#42044910)
I'll take your word for it—I'm currently blessed by working outside of the rails ecosystem so my knowledge is likely out of date.

EDIT: I'm not bothered by this, but this is a very odd comment to downvote. What on earth is so offensive or distracting about saying someone else is likely more knowledgable than you are? Very confusing.

Re:Rewrite it in Rails by skipants on Monday November 04, 2024 @01:19PM (#42044461)
I agree with you on all your points but I came to the conclusion that I would _not_ start a new app in Rails for those reasons.

I've spent my whole career on Rails and I think it's amazing when starting small but mature applications are a nightmare to refactor. Every monolith Rails app feels like it hits tech bankruptcy after ~5 years.

Re:Rewrite it in Rails by codesnik on Monday November 04, 2024 @01:27PM (#42044551)
"tech bankruptcy"! this is a VERY strong sentiment. First of all, I've never seen a rails-based company which has it problems from tech department, and not from product market fit or whatever, and that's in a 18 year carreer. I'm singlehandedly refactoring right now a 10-yearish rails app which had a period of neglect and bad contractors who broke every single test, and it is still very much manageable.
Re:Rewrite it in Rails by stouset on Monday November 04, 2024 @03:04PM (#42045492)
> I've never seen a rails-based company which has it problems from tech department

I've been using Rails since 1.0, owe much of my career to it, and still think it's an incredible framework that I love using.

But I have seen plenty of startups—mostly filled with junior developers—who don't have the maturity and experience to avoid some really bad ideas absolutely wall themselves into a corner. Thankfully the worst of this was in the Ruby 1.8 and Rails 2.3 era, but it still happens today.

A lot of the issue is the tendency that Ruby libraries have toward exposing internal details that end up getting relied upon (Hyrum's law in action).

Re:Rewrite it in Rails by lcnPylGDnU4H9OF on Monday November 04, 2024 @04:30PM (#42046180)
Hadn't heard of Hyrum's law before. https://www.hyrumslaw.com/

  With a sufficient number of users of an API,
  it does not matter what you promise in the contract:
  all observable behaviors of your system
  will be depended on by somebody.
(There's something about the way people manage to phrase these that I really enjoy. Something about the succinct and clear expression of an idea that's otherwise really fuzzy in my head.)

It's interesting to think about the implementation being necessarily coupled with the interface. In some context that's obvious, but the idea that another implementation can't be freely swapped in -- because nuanced behavior (sometimes called a bug) in the original implementation is still expected -- is one I hadn't, as such, thought much about before.

Re:Rewrite it in Rails by skipants on Tuesday November 05, 2024 @09:32AM (#42051714)
I agree it's a strong sentiment. But development seems to slow to a crawl at around that time from what I've seen. And then it seems like keeping the app going needs extremely strong developers around it, which not every company can afford. It's just bad value; you have to pay a lot to continue to develop at a normal pace.

I think the fact that we are trying to shove typing onto Ruby with Sorbet and RBS are a sign that maybe it's not the best programming language once you reach critical mass.

It's possible the grass is greener and this is what happens to every tech department... but I'm not totally convinced. I always hit a point with Rails apps where I can see the refactorings I'd like to make but I know it's not worth the pain of the inevitable `NoMethodError` at run-time in production. And that's _with_ a giant test suite.

Re:Rewrite it in Rails by dnh44 on Monday November 04, 2024 @02:03PM (#42044932)
Over a decade ago when Rails was the shiny new thing I wrote an online ordering system that batched received orders then sent out orders to suppliers for whatever the customers ordered. It was easy enough to get the app setup and it didn't often need any new features but I remember really struggling to get it up to date and working with each new rails version. My memory is clouded by both time and my inexperience at the time but even though the app was "done" it never actually felt finished because I felt the need to continually update to the new version of rails just in case I did want to take advantage of of the new features in newer versions rails.

Anyway over 10 years later now and I find myself writing an API and my initial thinking was to return to rails but then I remembered the bad experience (which was probably my own fault I acknowledge).

Now I find myself writing this API in Rust because the ethos that an app can actually be done is attractive to me. It's taking me longer to write but hopefully I've made a good decision!

Re:Rewrite it in Rails by cutler on Monday November 04, 2024 @03:10PM (#42045548)
Isn't the conclusion of this aticle that it's a bad idea, ie. Rust API?
Re:Rewrite it in Rails by dnh44 on Monday November 04, 2024 @03:44PM (#42045812)
I guess my post wasn't a critique of the blog post, it was a somewhat related story. I do actually agree with the blog post about not rewriting something that works. In my case it's a totally new project but it was my previous experience with Rails that made me not want to try it again for this particular project.

The API I'm working on is pretty simple and I want to finish it and forget about it so in my circumstances it seems that rust is a better choice.

Re:Rewrite it in Rails by RangerScience on Monday November 04, 2024 @02:48PM (#42045366)
Rails, ironically, doesn’t keep you in the rails. I’ve seen a couple of the things you’re talking about, and it’s really just mediocre devs in bad (but common) situations.

If someone gives you a paint-by my-numbers page, and you just scrawl all over it… is that the “fault” of the page?

Re:Rewrite it in Rails by wkirby on Monday November 04, 2024 @05:01PM (#42046414)
I think the context here is super important: I run an agency, and a lot of our clients are small startups or solopreneurs. The most important factors in determining their tech stack are (in some order):

* Time from idea to deployed solution * Ease of pivot * Ease of finding other devs who can take over

If I were a staff engineer at a large company with an existing tech stack tasked with spinning up some new internal microservice, I'm probably not choosing Rails.

But if I'm truly greenfield on a strict budget, still searching for product market fit? If that application ever truly outgrows rails (and it can become wildly successful without doing so --- look at stripe, instacart, github, shopify) then we've already won by surviving long enough for rails to be the problem.

Re:Rewrite it in Rails by bradgessler on Monday November 04, 2024 @02:09PM (#42044976)
> This is exacerbated by ruby's tendencies towards "fluent" interfaces, which is actually code for lots of methods that take undocumented hashes of arguments --- and hash access with strings and symbols? nightmare fuel.

Keyword arguments and pattern matching have improved this quite a bit, but not everybody is using it yet. I'm not sure how much Rails is using it either, which doesn't help.

It's def a dicey situation, but improving.

Re:Rewrite it in Rails by JohnBooty on Monday November 04, 2024 @01:39PM (#42044691)

    This is exacerbated by ruby's tendencies towards 
    "fluent" interfaces, which is actually code for 
    lots of methods that take undocumented hashes of 
    arguments
Well, I hate this too. I've been away from Ruby for 18 months but my impression was that the community has been moving away from that for a long time and toward keyword args (or whatever they're called, I forget)

    and hash access with strings and symbols? nightmare fuel.
What's the alternative? I like hash access with symbols. Prevents typos and the string values for the hashes are interned AFAIK.

    After running a number of rails applications in production 
    for going on a decade, this is really hard,
I don't feel that Ruby is worse than other languages I've used extensively (Ruby, Python, JS, C#) in this regard.

The issue is one's apps dependency graph. You keep dependencies flowing in one direction. Or you do not and you get spaghetti. I have not worked with languages that are really better or worse at this.

To take the example of a typical Rails app: it's very easy to add code to your Model A that depends on Models B, C, and D. Do that in a few models and...boom! spaghetti! Rails does not discourage or warn about this in the slightest.

It's relatively easy to avoid: have a rule that "no model can contain a reference to another model. if you have to do a thing that involves two models, put it in a service class" or some such. Of course, nobody ever does this.

Are there languages and frameworks that encourage/enforce The Right Thing in a more active way?

Re:Rewrite it in Rails by wkirby on Monday November 04, 2024 @05:04PM (#42046438)
> Are there languages and frameworks that encourage/enforce The Right Thing in a more active way?

I don't think so, as evidenced by the fact that I'm still so pro Rails after a decade of doing this. But that doesn't mean we can't be vocal about the things that still suck.

> I like hash access with symbols

Oh, I vastly prefer symbol access to string access, but this is really a ruby problem, not a rails problem. The fact that I can pass `{ "foo" => "bar" }` and `{ foo: "bar" }`, and my method has to either call `with_indifferent_access` or _strictly_ enforce being called with one of the two access types is a huge footgun, because improper access doesn't result in an error, it just results in a `nil`.

Re:Rewrite it in Rails by bhaak on Monday November 04, 2024 @02:01PM (#42044913)
> Typing efforts are fractured, and the official way is... well.. it's bad.

Official way? I thought there is none.

As long as there is no support for gradual typing in the core language it will never be used outside of niche programming.

And then I have a hard time imagining that Rails would use it anyway. Unless the performance boost would be tremendous.

Re:Rewrite it in Rails by rco8786 on Monday November 04, 2024 @02:04PM (#42044946)
https://github.com/ruby/rbs

is the "officially supported" one. It's terrible, as is Sorbet. No offense to anyone involved with either of the projects, they just miss the mark in pretty fundamental ways.

Re:Rewrite it in Rails by wkirby on Monday November 04, 2024 @05:07PM (#42046483)
Type definitions were introduced in Ruby 3. I personally think they are terrible --- primarily because they exist in sibling type files. They are arduous to write, don't have great tooling support, and don't feel like a part of the language at all.
Re:Rewrite it in Rails by Pxtl on Monday November 04, 2024 @02:15PM (#42045032)
In my experience, it's rarely the serving language that causes the hellscape of spaghetti. Possibly the SQL if you've got one of those weird luddites who wants all the business in stored procs running the project. It's the JS+CSS that does it.
Re:Rewrite it in Rails by jimbob45 on Monday November 04, 2024 @02:25PM (#42045153)
May I please ask what set Rails ahead of the .NET and Spring frameworks?
Re:Rewrite it in Rails by tmnvix on Monday November 04, 2024 @04:48PM (#42046320)
Avoidance of a proprietary MS stack is why I went with Django 15 years ago. I imagine this played a large part in the appeal of Rails at the time too.