Anyone find it suspicious how many companies put so much effort into justifying how Rails is still a good tech for a mature company?
I think the truth is really something like - we prototyped the app in Rails, because that's what Rails is good at, now we've evolved into a huge and slow application with no type validation, but porting the application and switching the team to something better and faster would be a nightmare, so we're just going to write an article about feeling good about where we're at.
Counterpoint: I find it suspicious that so many people on this forum take the opportunity to bag on Ruby on Rails every time it comes up. It's almost like they hate the fact that it is, in fact, a perfectly valid choice of language and platform, and they're trying to justify the self-flagellation required to use Java for web apps. I've been around the block a couple of times now, and done projects in PHP, ASP, .NET, and Java. But I've been using Rails whenever possible to make LOB CRUD apps for almost 15 years now, and there's nothing that can even hold a candle to it for productivity. Still. Things that can take just a line or two in Rails often take HUNDREDS in Java & <insert popular JS framework>, and be a nightmare to keep square with strong typing that's so popular with Typescript now. So go ahead, cast aspersions on Rails. I'll be over here, happily cranking out features as fast as my users request them, while the corporate IT departments at my Fortune 250 take 6 months to even put a request on their schedule.
EDIT: As an example, I once rewrote a web app for a department. The original was all Java/Struts. It took a team of outsourced developers 2.5 years to write. It took me 4 months to rewrite it in Rails (having no access to the code), and mine did the main operation twice as fast, which meant that you could do it online, instead of having to wait for a backgrounded process to finish and send email.
Rails is incredibly productive for 1-3 people to write something from scratch.
As soon as everyone committing code isn't synced up with the same knowledge and solution styles, it goes to hell fast. It's bad at surviving team transitions intact, bad for onboarding once the project is past its earliest days, et c.
Now, see, I would argue EXACTLY the opposite. I worked (briefly) for a Rails "house." I was assigned to a project that someone who had left the company had been working on, and told to add payment processing. I started working through the idea, putting stuff in the places it should go throughout the stack. About halfway through the process, I finally noticed some code that looked almost exactly like my function, "below the fold" of the text editor window. Then I started noticing that I had duplicated the little snippets of code needed in many files. They looked almost the same, and they were in all the same files. In fact, I realized that ALL the code to enable the processing was already done, and all I had to do was expose it on the page. To me, it was a crystal clear example that each bit of code needed to do something in Rails has a "correct" spot, and it's hard for me to believe that anyone with a nominal understanding of Rails wouldn't grok the organization, and naturally do things "the Rails way."
My experience doing agency work with Rails has been similar. Love or hate the opinionated nature of it, switching projects was fast because generally you'd just know where any given thing's home would be.
Some languages and ecosystems can be more helpful, though, even if none can save you. Rails is memorization-heavy and doesn't have static types to aid in navigation & reading. Its runtime auto-magic even resists grepping. Auto-imports mean you don't even get a decent list of which sources are contributing to a given file's behavior.
It's also the case that different teams can write it pretty differently, depending on gem choices and which Rails features they lean on. Plenty of other languages and ecosystems are like that, too, but all the above stuff means Rails is exceptionally bad, in that regard.
I totally agree that Rails is great at LOB CRUD apps. Apps like that don't get very large or complex, mostly do fairly simple transformations from a database, mostly have fairly simple validation and business logic, and can use a fairly small set of user interface components. I think the primary competitor to Rails in this space should be low/no-code frameworks that can do those things without requiring much or any code. I agree Java/Struts is worse for this, and that there is a huuuge amount of "dark matter" of apps like this out there to be written.
But! Gitlab is not a LOB CRUD app. And I think a lot of people here have been burned by ending up working on bigger more complicated projects that started in Rails because it was convenient and then persisted with it because it never became clear that there was a positive ROI in migrating to something different. Some people who have had that experience tend to be skeptical of projects getting started with Rails, because it feels like starting to dig a hole that they know may be difficult to climb out of.
But! You never really know whether some application is going to remain small and simple, or whether it is going to grow and become more complex. So everyone is just guessing based on very limited information about the future.
My two cents is that I like services. Not micro-services, larger services with well-considered boundaries, but which are not a single monolith. If that structure or philosophy is in place, I worry a lot less about implementing the individual services with Rails, because the future path is much more clear. If a particular service grows too big for Rails' britches, it can be replaced with a different implementation, without reimplementing everything. I think services are an extremely useful hedge against the risk of path dependency leading to implementations that are not working well, but are very hard to fix.
checkout elixir/phoenix. Its almost as productive as rails while having performance within the same realm as go.
pros: imutable data types. ruby like syntax. similar codebase organization. super fast. more modular than rails. the websocket system is way faster to develop in and deploy.
cons: no runtime metaprogramming but you do have a sophisticated macro system. not as many drop in libraries. not as many jobs for it yet.
Unfortunately Elixir just doesn't have the network effects of Ruby. Ruby support (libraries, SDKs, first class integrations) and popularity (ability to hire effective devs) is just an order of magnitude or more higher than Elixir.
I say this as a massive Elixir and functional programming fanboy.
network effects take time to develop. unfortunately it doesn't have a major company or foundation pushing it forward aggressively. That said, I'm hopeful. its defiantly the BEST platform for building anything websocket based. the killer apps for picking elixir will be anything requiring soft realtime.
case in point, I built my startup in elixir. completely agree on the difficulty in hiring but its not hard to teach. It was harder for me to find people who knew sql well. Unlike active record, ecto embraces sql so you have to know sql to use it.
anyways, its time will come. more and more companies are adopting it from discord to supabase to <cringe> trump media group.</cringe>
I've heard this time and time again but I just don't buy it. The only similarity between Ruby and Elixir is syntax and even there I'd say it's a superficial likeness. Beyond that Elixir and Ruby are almost diametrically opposite. Elixir is functional/immutable whereas Ruby is mutable/OOP. Languages such as Elixir and Clojure were designed to counter the OOP trend and its mindless disregard for mutation. So, anyone who is really into The Ruby Way is going to have to disrobe before entering the temple of Elixir.
Yes the syntax, but also many of the libraries and conventions are the same. The package management/build tool has a lot of similarity as well. When learning a new language, learning the standard library and the many conventions is a lot of the friction. With Ruby -> Elixir that is a lot less.
Also, I think you underestimate how many people (such as myself) who use Ruby in a very functional way already. Immutability is really not all that different. The only thing is you can't use ! methods and instead have to assign. For example instead of `array.sort!()` it's `array = array.sort()`. It's really not that hard, and in fact I found it easier because I didn't have to remember if `array.concat()` mutated or not.
IMHO the only "hard" things for a rubyist to learn are pattern matching and Actor model (OTP) concepts. Actor model concurrency is definitely different. But for an experienced programmer, that can be learned in a couple of hours (or less).
Cons: missing community, a lot less well maintained libraries, needs more wheel reinvention, impossible to hire experienced developers, far worse tooling and editor support.
The community was there, at least that was my feeling when I started learning Python around 2003. What wasn't there was of course almost anything web-related, for my first "website" in Python I had to resort to using mod_python, which was a perfectly fine project in itself but which wasn't giving you the same instant gratification as PHP did when it came to the web. (there was also the Zope ecosystem, but that's a subject in itself).
Elixir performance similar to Go? That's stretching it a bit. Elixir is fast within its own niche - network I/O - but it's a dynamic language so can't compete with Go on, say, heavy calculations or other CPU-intensive tasks. Elixir doesn't even have a vector data structure, relying instead on Erlang's very clunky offering.
yes I agree its not as great at cpu intensive stuff. but most people are using go in networked applications where network I/O IS the bottleneck
that said, elixir has excellent interrop with rust via rustler for when you need those heavy caclulations. and I trust a rust implementation long before I'll trust one in go.
and as far as lacking a vector data structure, sure but there's been a lot of work into Nx. who cares about a vector data structure when you have a full power numerical processing library complete with tensors! and unlike python, you can combine it with genstage and broadway to do all kinds of crazy shit.
That's like asking why there is a car doing 60mph on the highway when everyone else is doing 75mph. If they are driving a VW, would you assume that means VW makes slow cars?
> That's like asking why there is a car doing 60mph on the highway when everyone else is doing 75mph.
thankfully in my country being too slow on the highway (lower limit being 80 km/h apparently) will net you a fine. It's people's right to drive whatever van they fancy... as long as this does not have any too much negative influence on society.
Okay, come on! That is fking Struts, it is hardly a fair comparison. Though otherwise I agree that Rails is a great choice for almost every CRUD app, like we really should stop overstressing it. Just use whatever one we are comfortable with and has enough internal knowledge on and with modern computers it will be plenty fast enough.
This whole thing happened about 4 years ago now, and the original application was written several years before that, before the rise of React and Angular, which have BECOME popular (IMNTBHO) because they try to address the gaping hole which is the frontend of using Java for web apps.
Around that same timeframe, I tried using JHipster, which sort of attempts to do for Java everything that a Rails app stack does for Ruby. It took 45 minutes for my top-of-the-line Dell laptop/workstation to bootstrap it, and it was... unapproachable.
Why did you use Struts 4 years ago? That framework died at least a decade ago.
But don’t get me wrong, I see where you are coming from, I’m just saying that your experience may not have been up-to-date even then, let alone now. In practice, with spring boot, quarkus and the like developing a backend app is plenty productive in java.
Ay yi yi. Maybe go back and reread what I wrote. I didn't use Struts, and the original app was written at a time when that was an accepted "meta."
I've used Spring Boot. We'll have to "agree to disagree" that it's "productive."
All these things that people are stacking on top of Java are just trying to implement concepts and features that Rails has had for 15 years, and they're still nowhere near as "productive."
Interesting! I'm wondering since you have programmed in PHP, what has been your experience with that? I assume you would be using web frameworks like Laravel or Symfony or equivalent. Does Rails still beat those like it did Java and <Foo>JS?
Laravel is pretty amazing, and with modern PHP the languages are pretty comparable. PHP still has a reputation problem though, and hiring has been tough because so many PHP devs haven't used Laravel (or Rails) so they have a bit of a steep learning curve. The tooling for ruby/rails is also still a bit better than laravel, but that may not be true forever.
Do you think it's fair to compare something written in Struts to a modern Java framework like Spring Boot or Quarkus? I'd bet that it would have taken a similar time to rewrite in one of those frameworks as it took to do your rewrite.
As LesZedCB said, LOB is "Line of Business". In practice, this is where your business-logic resides.
edit: CRUD means Create-Read-Update-Delete. It's a basic programmer term for a simple application, or those simple parts of it at least. Even something big like Wikipedia, at it's core is a CRUD site. Most things are, with business logic sprinkled in; but some things aren't CRUD at all (eg a video game).
For example, if you're a car dealership your LOB CRUD API would handle stuff like submitting new cars, or staffs, or associating a sale of a specific car with a specific salesman or whatever other biz logic you have. This could be in contrast with, say, your Document Storage CRUD API which handles integrations with your document storage (eg storing things on a SharePoint, or Ceph, or S3, etc).
LOB has no inherent value with regards to microservice vs. monolith, it's simply another way to refer to the business specific logic. The term LOB is common across business as a whole, whereas "business logic" is generally a phrase used by programmers about programs.
By "LOB CRUD" GP means those fairly generic apps that are mainly a front-end to some database, with a bit of business logic or integrations tacked on. They're not the apps making money for a business, they're just helping it tick along and do the things that actually bring in revenue.
Companies justify using Rails publicly because it makes financial sense.
There's this meme that Rails "just doesn't scale" and is "yesterday's software", but neither are necessarily true. Ruby isn't the fastest language, but it's now competitive enough that the same critics might as well throw Python under the bus while they're at it. There's things I don't like about both Ruby and Rails, but it's a perfectly viable and productive way to build websites. A very scant number of businesses need to be at the scale of Twitter or The Google, in which case Rails can be a great choice.
But I imagine Rails is being increasingly dismissed by newbie developers as being obsolete and not-cool. Mature companies may realize it's in their best interest to communicate that their boring-tech works just fine and that they have no plan on changing to cool-tech. If it's true, then someone's got to say it, right? Someone needs to be interested in working with Rails. Not every business has the money to waste converting their old apps to cool-tech like Elixir or a React frontend with microservices.
> Ruby isn't the fastest language, but it's now competitive enough that the same critics might as well throw Python under the bus while they're at it.
You say that like it's a point in support of Ruby, but, yes, absolutely, Python should be thrown under that same bus. Both languages are dramatically slower than other languages that are available. My little hobby programming language with a bytecode VM I wrote myself in a single C file is faster than Ruby and Python. It would be hard to design a language that isn't easy to make faster than Ruby and Python.
They both pay an incredible runtime performance cost for their deep support for dynamic runtime metaprogramming and mutability. If you don't want those features, I don't think it makes sense to use those languages.
I would argue the eventual "bogged down" feel of a Rails application isn't ruby itself. It's rather the abuse the database takes because ActiveRecord allows you to lazy load records so easily by abstracting SQL calls, so you're hitting the database many times per request and not realizing it until you get bitten. There is an option to disable lazy loading at a project level, but I've run into gems that assume it's enabled.
For comparison, elixir's Ecto doesn't allow lazy loading
In addition, for things that can't be done easily with ActiveRecord, you can write your own SQL, but then you really need to know SQL to get the performance right.
Where I work, our main product is a Rails monolith, over 10 years old at this point. The few serious performance issues we currently have are due to complicated SQL queries written back when the DB was much smaller.
I guess part Hyrum’s law in that big projects depend on implementation details to a degree, related but many C extensions (though Graal can run these as well, but perhaps not all of them), and last I read about it, the JIT compiler is not yet that good at optimizing very big applications — it takes a really long time for some functions to become hot enough.
I think it's just that the very largest codebases are the most likely to end up depending on obscure bugs in Ruby or the surrounding ecosystem itself, or maybe features that basically nothing ever uses except that one file buried deep in that one gem that three real programs use. Ruby apparently has a lot of stuff like that.
> But I imagine Rails is being increasingly dismissed by newbie developers as being obsolete and not-cool. Mature companies may realize it's in their best interest to communicate that their boring-tech works just fine and that they have no plan on changing to cool-tech. If it's true, then someone's got to say it, right?
That's precisely the problem. If engineers were a dime a dozen, then Rails could be a great choice. Boring tech is a great place for businesses to be, in theory. Back here in reality, finding engineers is pretty hard, and the ones who we can find, are all only interested in working with Cool New Shiny Toys. If we posted a Ruby ad, we wouldn't get any bites. It's not used here.
Boring tech is great, until it becomes a noose to hang yourself with.
We've not had a big problem getting candidate streams of people who want to work with Ruby. In a way I don't mind having an implicit filter against people who only want to work with shiny new things, as we don't really want our platform filled with everyone's favorite shiny technologies any more than we need a shiny language to write a good-sized e-commerce web app.
> That's precisely the problem. If engineers were a dime a dozen, then Rails could be a great choice.
If engineers are hard to find then isn't using a framework that maximises developer productivity the way to go? Rails definitely falls into that category.
Related, we recently advertised for Rails and React engineers. We had about the same number of applicants for each position but the Rails engineer quality was in general higher than the React engineer quality.
> If engineers are hard to find then isn't using a framework that maximises developer productivity the way to go? Rails definitely falls into that category.
Languages are not like cars. You cannot take a professional Rust engineer and drop him into a Ruby environment and expect him to be immediately highly productive, as if you were switching him from a Miata to a Ferrari. Languages need to be learned all over again, their ecosystem needs to be learned, beginner code needs to be reviewed by someone senior who is more familiar with the language. You can't just make an executive decision to go with Ruby because it has a reputation for productivity and expect immediate productivity gains.
> If engineers were a dime a dozen, then Rails could be a great choice.
Are they not, though? The narrative is that there's simultaneously too many engineers coming out of school and yet it's extraordinarily difficult to hire engineers. Which is it? Or are most engineers really that bad that they're unhirable?
> Back here in reality, finding engineers is pretty hard, and the ones who we can find, are all only interested in working with Cool New Shiny Toys.
I definitely believe you, but I wonder how much of this is self-fulfilling. Maybe a lot of engineers get into cool-tech because more jobs are demanding it, and their perception is they'll be quickly obsolete if they work with boring-tech. Most newbs seem to look towards startups first, which are going to be using cool-tech a lot of the time, but there seems to actually be a lot of interest on HN in working with boring-tech at either nontech companies or BigCo.
> The narrative is that there's simultaneously too many engineers coming out of school and yet it's extraordinarily difficult to hire engineers. Which is it?
It's both. You need to be a large company to hire junior talent. The local market is mostly startups without well-developed production guardrails and well-gardened, too long backlogs. The large companies cherry-pick for the relatively few junior positions that open and they aren't using Ruby internally. Thus the Ruby ecosystem hasn't developed here.
> but there seems to actually be a lot of interest on HN in working with boring-tech at either nontech companies or BigCo.
HN trends senior talent which has been around the bloc enough times to know that stacks change and people don't. Most of the labor market comes into interviews and want to impress you with how many languages they know.
It's not hard to hire an engineer that can take a ruby on rails project and run with it. There's mountains of tutorials and books about it. You don't need the best of the best for this.
Some people have decided that that isn't good enough for their company though.
No language book can genuinely teach you the ecosystem for that language. The ecosystem is many times larger than could ever possibly fit into one book, but the ecosystem is what provides you with the libraries you actually reach for to build things day-to-day.
Expecting engineers to self-teach from a book is practically begging for NIH syndrome and a rewrite in two years.
I bet you wouldn’t hire me, even though I am a very competent developer with a long resume. The problem is narrow minded hiring. I have never had problem hiring good people.
> Not every business has the money to waste converting their old apps to cool-tech like Elixir or a React frontend with microservices.
I always ask myself (and the team at large) "how much time/effort will it take to reach parity using the new tool-set?". The answer usually settles the debate immediately.
In my experience, scaling RoR is totally doable, but very tricky, as the both language and associated frameworks are very terse, opaque and by default seem to do the thing that does _not_ scale well. Because of all this magic, you have to be somewhat of an expert to avoid all the foot guns.
As a new shop, without a known depth of knowledge and talent, I'd probably avoid Rails if scaling is a concern, but if I'm Gitlab or Shopify or some place with world class Ruby engineers, I'm staying the course.
> Someone needs to be interested in working with Rails.
A lot of us are. I don't think Gitlab is in any shortage of resumes...I tried. Might be the market collapse or whatever reason, didn't even get past the initial HR interview. It's also possible my country of residence isn't high on their list...we are expensive.
> But I imagine Rails is being increasingly dismissed by newbie developers as being obsolete and not-cool. Mature companies may realize it's in their best interest to communicate that their boring-tech works just fine and that they have no plan on changing to cool-tech
I dont think that's the case. I think Ruby is dismissed because it's not a boring language, but has none of the safety of the other "shinier" languages.
I've worked on some huge rails apps, and I don't agree at all that performance is poor at scale. You might need an extra instance or two to handle the same traffic load, but in every codebase I've seen, the problems of slowness are related to database access, slow/unoptimized calls to other services/APIs, etc.
I actually disagree that it's suspicious. I think there are often trends in programming that despite being touted as newer, better, and faster have failed to deliver on that. Ala the amazing amount of churn in JS frameworks in the earlier years of SPA's and such. An article saying y'know what "X is actually good enough" isn't any more suspicious than all the articles saying "Y is the new hot thing".
I am biased here because with respect to the products that I've helped create the speed of ruby vs js, python, etc. has never been a dealbreaker.
Even if porting an entire application wasn't a nightmare, why would you ever do it unless your organization was going to fail without? Porting entire applications needs to be justified by some critical requirement that (in this case) ruby/rails isn't meeting.
Because Rails is a good technology for a lot of use cases.
If you want to develop a simple crud style app, with user login, mail sending and all that stuff it is highly productive.
Performance is okay and certainly good enough for the average web project.
Just get rid of the weird parts like turbolinks (unnecessary and messes up a lot of js) and don't write APIs using it (can't even rename fields easily).
There are similar Frameworks in other languages and they all have pros and cons.
Imho when it comes to web frameworks there is way too much emphasis on the startup style company and the ones with huge traffic.
Companies doing grunt work style web development don't waste their time on flavor-of-the-month.js.
If you build a website for a niche company to sell odd machinery on, you have to get shit done and you will never need to scale.
That means reliable, batteries included, highly standardized and easy to use. Rails ticks those boxes really well.
> Imho when it comes to web frameworks there is way too much emphasis on the startup style company and the ones with huge traffic.
That's exactly what is making web development decreasingly enjoyable as the years go on.
~99.5% of the web doesn't need the hyperscalable cool-tech du jour one typically reads about on HN. As long as developers don't fall for footguns, there's a lot that can be accomplished even with a language runtime like MRI. If scale becomes an issue, those things can be solved through horizontal scaling, optimizing database queries, not doing stupid shit that's memory-hogging, and moving expensive algorithms into another language. Ruby is perfectly adequate for serving HTTP requests. Whenever I've worked on a Rails app that everyone was frustrated with, the problems were almost always a compound of a bunch of dumbass shit that various developers piled on without much thought (otherwise I'd have seen them discussed in GitHub or Pivotal stories).
In another comment, it said Gitlab moved off ActiveRecord.
The fundamental problem with rspec + ActiveRecord is for each test: you create db state (tons of inserts), run the test (more db reads and writes), and then tear down the state. This is very expensive when you have 100,000s of tests each taking 500ms.
Rails/rspec does not make it easy to stub db state with ActiveRecord.
Does this mean if you only want to run the tests for `users_controller` during development, you still have to load the fixtures for all other tests with each run?
In the normal case. When you start a test it loads from fixtures into its own database.
Any test can make use of what is in that database. So you tend to put a bunch of stuff that is useful for most tests.
If a specific test needs an unusual setup, then it can do whatever is needed to load data. Generate data, load extra fixtures, etc. You can do this on a per test basis, or a group of tests, etc.
An option is to reload everything between each test. Not recommended.
Normal usage is to rollback any changes a test did, so that each test has a clean slate. This tends to be plenty fast. Parallelism can usually be done.
If speed is still a concern, you can get fancy and load up multiple databases with fixtures and divide tests between them. Maybe have 2-8 sets of tests running at same time.
It's been a few years, but I've inherited test suites that take 14 hours and been able to get them down to a few minutes with above techniques.
Something like Guard can be setup to automatically run tests relevant to what you're working on. So you don't have to run full suite each time.
> Every tiny rails app that uses rspec ends up with +1hr test times due to tight coupling between activemodel and the db connections.
Wat? I mean test times aren't great but I've got several thousand specs for what I would call a medium-sized application that run in <1m using TurboTests or <3m using rspec alone. I can't imagine a "tiny" rails app that takes an hour to test. Maybe you're doing a lot of browser rendering or something? My app is API only.
I think the fundamental design problem for rspec is for each test you create db state (tons of writes), run the test (reads and writes), and then tear-down (truncate). Each test is at least adding an authorized user (and then removing it) at the simplest and at the worst creating complicated db state to support relational models that must be added and torn down with each test (database_cleaner).
Gems like Fabricator or FactoryBot also make the "create db state" even more excessive, because developers would be lazy and use factory methods that create more than they actually need for the test.
For example, one project I stored a tree-structure that could be modified by api calls. Each test required re-creating the 15 node tree + each node's relational data (think node = user and all users must have a profile, authorization scheme, etc.).
I never figured out how to avoid resetting the db state for each test case.
This isn't an rspec problem, it's a Factories-for-ActiveRecord problem.
The two main options to mitigate are:
- just work with in-memory objects (FactoryBot using build or build_stubbed, or just MyModel.new) and stub/mock finders as needed,
- or there's this thing people like to hate that was introduced in Rails 1 called test fixtures, which allow you to prepopulate the database with some initial data and then your test just runs in a transaction and rolls back.
The best suggestion I've heard recently (though I can't recall where to give credit) for managing complexity w/ fixtures is to write an extremely minimal fixture set aiming for 2 instances per model with minimal data required to be valid, and then customize it as part of your test. For a blog example, that means you have two Posts in your fixtures and would write a test around drafts by updating one of them to draft status (be it state, toggle, or publication date) and then test your query, or controller, or whatever. This keeps the data churn inside each test minimal, while keeping the out-of-scope data minimal as well -- if there's only 2 blog posts, all your tests can assume there will be one you care about and one you don't, which is useful for testing filtering/search/visibility/authorization/etc while remaining pretty consistent.
> - just work with in-memory objects (FactoryBot using build or build_stubbed, or just MyModel.new) and stub/mock finders as needed,
Mocking the finders is obnoxious, since ActiveRecord returns a relation class, not an array. Plus stubbing out relational coupling isn't easy (e.g. the user model might have a `company_name` method that delegates to the company table.).
> - or there's this thing people like to hate that was introduced in Rails 1 called test fixtures, which allow you to prepopulate the database with some initial data and then your test just runs in a transaction and rolls back.
Fixtures and Factories have the same issue are vulnerable to inserting unnecessary data for the test. Models may have validation requirements that must be satisfied to be stored, but completely unnecessary for the test. For example, all users need a `company_id` with a foreign key constraint, so to test _anything_ on user, you have to insert a valid company as well.
Maybe I need to re-evaluate fixtures though, since they would be simpler to run than a factory.
The idea is that you write one set of fixtures for the whole app that you then use in all tests. You'd have a valid company and a valid user in your fixtures, but that's fine because you probably want to test both the company and user models. In the user model tests, you can ignore the existence of the company fixtures, and vice versa.
Since the inserts only happen once for the whole test suite, the marginal cost of adding more fixtures is minimal, so it makes sense to just make the fixtures as complete as possible.
interesting. I haven't used fixtures before. Wouldn't this make individual tests slow (like in development?) since all fixtures must be inserted all the time?
It doesn't add as much overhead as you might expect because the fixture data is inserted into the database without instantiating any ActiveRecord models. Unless you're loading a truly crazy amount of fixtures (gigabytes?), the database can ingest all the data in single-digit milliseconds.
In addition to that, the test suite performance was regularly monitored. And like any performance issue, we'd instrument and then fix issues as they came up.
(duplicating another comment I wrote to hear your thoughts)
The fundamental design problem for rspec is for each test you create db state (tons of writes), run the test (reads and writes), and then tear-down (truncate). Each test is at least adding an authorized user (and then removing it) at the simplest and at the worst creating complicated db state to support relational models that must be added and torn down with each test (database_cleaner).
Gems like Fabricator or FactoryBot also make the "create db state" even more excessive, because developers would be lazy and use factory methods that create more than they actually need for the test.
I don't exactly agree that it's a design problem. I think there is a lot of value in testing at a high level (controller tests) and having them touch the full stack (down to the DB). Gives a lot of confidence that the code will work in production. Throwing money at it (running the tests in parallel) pretty much solves it.
I have seen FactoryBot use get out of control (creating 8x as many records as you'd expect). That's a really easy way to slow down a test suite :). One way I've found to fix that is by adding tests for the factories, and asserting they are only creating what you want them to.
On model tests, another thing GitHub did well was encourage using `.build` when possible to avoid writing the the DB.
> I think there is a lot of value in testing at a high level (controller tests) and having them touch the full stack (down to the DB).
There is a lot of wasted work. Each (similar) test would insert and then delete the same rows, but make a little tweak.
Other languages and frameworks (java, python or golang) don't need to test the db and run super quick. Most db systems do not actually need to be tested. e2e testing can be done manually via curl or qa.
> Throwing money at it (running the tests in parallel) pretty much solves it.
Tests still are slow locally.
> One way I've found to fix that is by adding tests for the factories
That is interesting. I had a meta-test that would limit the number of sql queries a test could trigger.
> Anyone find it suspicious how many companies put so much effort into justifying how Rails is still a good tech for a mature company?
No. I would imagine these articles are coming out as a response to people claiming Ruby is outdated tech when it's still perfectly viable. And I say this as someone who has happily moved on from it.
And I would hardly consider a blog post or two "a ton of effort".
Elixir. And it wasn't "because Elixir looks like Ruby"--in fact, I personally found having it look so much like Ruby detrimental at first since the similarities end at syntax. I had a growing interest in functional programming and in improving a multi-user web app we were building. Elixir's (really Erlang's) concurrency model is the first I've ever been comfortable with and able to build a clear mental picture of what's happening. The syntax (for creating concurrent processes) is a wee bit gnarly, of course. There's no perfect world :)
As it stands, if I were to ever want to work in OO again, I would go back to Ruby. It's still my local-scripting language of choice for things that are too annoying to do in bash.
OK. Elixir is a no go for me, there's zero jobs where I live and I don't see this ever changing.
It leaves Python, it was the second most enjoyable (to me) after Ruby, and Django is fine. Node is simply too hectic with new frameworks coming in every week and Go...oh boy.
Hey I understand how I sound, I'm privileged to be doing this job and get paid what I'm getting paid that it's a bit ridiculous to be stressing over stacks. Some people's jobs are to fight for people's lives in Emergencies Rooms or keep public order in dangerous neighborhoods and here I am not pleased that I might have to switch from Ruby to Go lol.
> Where do you live?
Sorry for the paranoia but ever since I'v found out you cannot delete accounts from HackerNews I tend not to reveal too much personal info. But lets just say that on quite a large radius there aren't any Elixir jobs available to me and Ruby is drying up fast as well. And I don't think 100% remote is something I'd be happy in long term.
I complain about work all the time, I didn't think you sounded like anything :D
> Sorry for the paranoia
No worries--I thought of that after hitting submit. And ya, there are some jobs where I live but I work 100% remote in order to be at a company that uses Elixir and pays me far more than my own country would. Although I'm super happy with 100% remote. I've already blown off one of 2 company meet-ups this year, lol (though really that was more about having to travel).
> so we're just going to write an article about feeling good about where we're at.
I've been doing rails for years now, I have yet to work for a rails shop that is living in denial about the state their app. The batteries-included nature of rails is easily worth the cost of no type validation in most companies I've worked for, and the teams I've worked with that lean into JS more tend to be much, much bigger with a lower developer throughput.
IMO it's a much more sane world to be in than JS and React where best practices change every year or two but the company repos can't keep up. So you wind up digging for solutions to problems that React no longer considers to be a best practice and is therefore buried underneath a pile of Medium articles discussing the new right way to do things.
This isn't about truth-telling, it's about impressing enterprise prospects with the _relative_ and self-described simplicity of a basket they are considering putting some/most/all of their apples in.
Given Gitlab's fairly transparent chronicling of what they've learned and how they work, I disagree. One of the things I like best about Gitlab (as an organization) is their ongoing effort to conduct business and process learnings in public, and share them.
I don't get the case that Rails is not working out well for them which is implied in your answer. What is the "better and faster" tech here that would have made a big impact on their business?
I mean, you have to justify being stuck somehow. While GitLab is certainly not an average Rails project technical debt-wise (I'm a tiny-time contributor to GitLab and my experience was quite amazing), but it's still Rails & Ruby all the way down there which could get you going only so much. You still have to write shitloads of tests, most of which are doing a sum-types-able programming language compiler's job over and over again. One day you realize this and that's the day Ruby is dead for you because there's no chance in hell you can persuade your peers to use measly dry-rb (dry-rb maintainers — no offense, I'm admiring your stellar work), not to mention moving to F#/Ocaml/Haskell/Rust.
At least in Gitlab's case, I think this is spot on.
My biggest complaint about it is that it's slow, and as of the last time I used it so many of its functionality didn't auto-update until you hit refresh.
I don't know enough about web development to understand whether this was a Ruby on Rails problem or a Gitlab problem.
Rails has a lot of "magic". Which is fine if you only hire veteran Rails developers who know the magic, but over time it becomes organizationally exhausting because ultimately you will have to train people, you will have people leave the org, and you'll have people coming from other orgs with way less conceptual overhead that keep asking "why don't we just..." to methodologies outside the core rails ecosystem.
Rails is perfectly fine but being perfectly fine is an unsatisfactory outcome over time.
Also problematic is that gitlab really really cares what programming languages you've worked in before. I've applied and they've turned me down because I didn't have enough Ruby experience, nevermind that I have plenty of years of experience in development and learning another language isn't that big of a deal.
Ruby has had it's heyday. It's 15 minutes of fame was a decade ago. If they persist in using Ruby and only hiring people with extensive Ruby experience, they're going to run out of talent AND have to pay over market rate to get people in their specialization. Like all the banks and governments forking over loads of cash for COBOL and Coldfusion consultants because the refused to modernize.
> If they persist in using Ruby and only hiring people with extensive Ruby experience, they're going to run out of talent
The best time to become a Ruby programmer or run a bootcamp teaching Ruby was five years ago. The second best time is now.
> Like all the banks and governments forking over loads of cash for COBOL and Coldfusion
Ha.
> learning another language isn't that big of a deal
Actually Ruby has a very specific and long-standing style that is subtle and takes a while to pick up. Any Rubyist worth their salt can instantly spot code that's simply been "ported" over from some other language community. Ruby has a "Ruby way", which in large part inspired the "Rails way". It's frankly insulting to claim you can just pick up Ruby on a whim and it's no big deal. Sure, Ruby isn't hard to learn at first, and I encourage all beginners out there to give it a real try. You won't be disappointed. But Ruby is also a deep language with a rich vocabulary, and it will take you some time to master it. In some ways, if you're an experienced programmer from another language community, it'll take you longer—because you'll need to unlearn the habits you've picked up before that in Ruby might be considered a code smell.
I suggest you spend some time gaining actual Ruby experience, and then next time you apply for a job asking for Ruby experience, you'll have some. :)
Ruby has been steadily going down as favorite language for years. I have absolutely no beef with Ruby, but GP is pretty clearly pointing out the disjunct between continuing to use a language with a dwindling userbase, and requiring that userbase to have professional experience. In its home country, GitLab is one of the few to use Ruby to begin with.
>I suggest you spend some time gaining actual Ruby experience
Which requires those people to get jobs. If they can't get jobs in the language, they can't get experience in the language. This is already an issue with the more popular languages which are converging to the same point.
>if you're an experienced programmer from another language community, it'll take you longer—because you'll need to unlearn the habits you've picked up before that in Ruby might be considered a code smell.
So much this :)
I've been a C# developer for over 20 years and I also write quite a bit of Go. I recently decided to write my NFT app in RoR with backend / batch processes in pure Ruby, and having essentially minimal experience with Ruby it has taken a while to unlearn some of the things that are nearly instinctive to me with (particularly) C#.
That said, so far I am really glad I did what I did. I love Ruby and I think it's incredibly underrated, especially vs Python (though Python is also a great language on its own). Once you really get a handle on Ruby (and Rails), it makes web dev a fun again.
> Also problematic is that gitlab really really cares what programming languages you've worked in before. I've applied and they've turned me down because I didn't have enough Ruby experience, nevermind that I have plenty of years of experience in development and learning another language isn't that big of a deal.
Yeah, I've come across this in loads of companies too. In the end, I think those sort of companies don't understand that once you grok 2-3 languages, the rest of them mostly look/work the same (except the really different ones), and they are just looking for "code-monkeys" to program with them for a year or two.
> But if you know 2-3 closely related languages, one that isn't closely related to those 2-3 can be problematic.
Indeed. Not sure if you left it out on purpose, but my comment included (right after the part you quoted) the following: "(except the really different ones)", which covers exactly what you're talking about :)
I don't think most people simply "accidentally grok" or use Smalltalk, Lisp or Raku; therefore I consider most people don't have what takes to grok Ruby either.
Oh please, Ruby is not some arcane language. It's really not all that different from Python, JavaScript, Java and C# once you get used to your dev environment. Those languages alone cover way over half all the developers.
People here are acting Ruby is anywhere on the same level of difficulty for a regular high-level OOP developer as C++ or Haskell.
> It's really not all that different from Python, JavaScript, Java and C#
I think that being able to dynamically replace behavior from almost anything at any point in your program is pretty much very different from Python, Java and C#.
The only other mainstream language with this capacity is Erlang, and Erlang is not exactly what I would call mainstream language.
And you believe that Ruby both does not make it easy to learn this concept and makes aggressive use of this concept?
I believe you're severally overestimating the impact and importance of one quirk when many developers are picking up wildly differing languages and decently successful at it all the time.
> I think that being able to dynamically replace behavior from almost anything at any point in your program is pretty much very different from Python, Java and C#.
Sure, but it's a very popular language that puts the ability to modify behavior at run-time front and center. It's not like Ruby is special in that regard.
To be fair it takes a ton of memorization to be productive in a Rails codebase, between lack of static types and tons of runtime "magic". Requiring Ruby experience is silly if you've managed to write in several languages productively already—Rails experience, though, I could see requiring that. Recent Rails experience, even.
Which is part of why I've pretty much sworn it off forever, after working on several Rails projects over the years. I never, ever want to onboard to a Rails project again, if I can help it.
It could also be that they didn't want to hire you because you aren't a 'believer' in the technology (in that you're not already experienced with it).
They have doubled down on Rails, so if they hire people who aren't already in the ballgame, they will either be faced with people who want to change things (which creates conflicts) or have to train people to avoid the speed bumps in the existing system (which also pushes people to want to change things).
I'm curious, was your position during the interview that you were beyond excited to pick up Rails as your next technology?
Finally, you never know... their feedback might have also just been a kinder let down... maybe they didn't feel your programming chops were up to their required level. Who knows...
> Like all the banks and governments forking over loads of cash for COBOL and Coldfusion consultants because the refused to modernize.
COBOL itself it's actually very cheap and simple; in fact "so simple anyone can use it because it's just english" /s
What banks and governments fork loads of cash for, it's a highly vertically scalable, performant and redundant system that works (and keeps working) under heavy load and concurrency. A SaaS cloud (including the ludicrous prices you pay for a SaaS when you need to scale your service...) before SaaS clouds were a thing. A mainframe computer with a support contract.
>"Also problematic is that gitlab really really cares what programming languages you've worked in before"
I agree that for experienced developer requirement to have extensive experience with particular language may not be all that important.
But rewriting perfectly working software just because developers knowing legacy language is too expensive is a big mistake. They would waste way way more trying to implement a perfect copy of the old system with "cheaper" developers.
I think the truth is really something like - we prototyped the app in Rails, because that's what Rails is good at, now we've evolved into a huge and slow application with no type validation, but porting the application and switching the team to something better and faster would be a nightmare, so we're just going to write an article about feeling good about where we're at.