Interactive "rails new"

I believe that there would be extraordinary value in documenting exactly what gets added when a framework is installed, and what gets removed when it’s removed. Being forced to make all of these decisions with potentially scary and regrettable consequences down the line is anathema to the Rails doctrine. And it’s shameful things are like this, given that it’s relatively easy to remedy and I thought that the whole reason we endured the pain of modularization around Rails 3.0 timeframe was to make this kind of thing easy.

This documentation is a major step towards being able to dynamically install and remove frameworks as easily as we try out gems. It also lets us move people towards feeling comfortable with Webpacker faster. For example, just asking people if they need jQuery to be available globally as a plugin (so it could be added to package.json and config/webpack/environment.js) would cut down yak shaving dramatically for many people.

Parting thought: I sincerely believe that Turbolinks is one of the best things to ever land in the framework. I feel a visceral pain when I see people talk about removing it by default. What’s needed is education for people who aren’t so comfortable in modern JS to understand why their non-idempotent code is going to break in a re-entrant scenario. Turbolinks isn’t the thing that is broken. Turbolinks is a linter for code that isn’t aging well.

5 Likes

Jonathan, Yes, I use the term from the generated comment:

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
# require "action_mailbox/engine"
# require "action_text/engine"
require "action_view/railtie"
require "action_cable/engine"
require "sprockets/railtie"
require "rails/test_unit/railtie"

If you use any of the --skip-action-cable commands you get the full list in config/application.rb

And rails app:update courteously assumes that after you have one exception, that during upgrades new ones should be added as comments.

Having something interactive for new/upgrades or something more general like an enable/disable task, flag, or config would be useful.

Personally I like the apache a2enmod/a2dismod, perhaps a task could toggle the require and comment in/out an accompanying initializer.

What is your motivation behind removing parts like ActionText, ActionMailbox, etc.?

My motivation for removing them for myself? Or from the default rails install?

For myself, it’s that I will not use them.

For the default, it’s two fold. For one, I imagine most folks building Rails apps won’t use them. That’s just speculation though.

Only some types of apps need a rich text editor. Many purposely avoid it. Many use client side frameworks.

ActionMailbox is one that I believe is misplaced. That sort of work should be done by a service-oriented architecture. My frontend webserver is the wrong tool for the job. In a world where people are struggling to maintain ever growing complex rails apps, it doesn’t seem like a good idea to encourage adding that complexity from the get-go.

It may very well be a valuable library, so I’m not discounting that, I just think that most would be better served by exploring other architectural patterns than “put everything in one Rails app because Rails comes with everything by default”.

2 Likes

Bootsnap is a rather invasive gem, for example patching the ruby Kernel require and load methods, and more. I prefer to use as few things like that as possible in order to avoid strange problems, unless they solve a critical problem for me. Startup time is not such a critical problem that I’m willing to take the hit on environment complexity.

2 Likes

I was on the fence about this one. In the end, I don’t understand it well enough to opt-in to its additional and unknown complexity at the beginning of a project when the startup times are the fastest they’ll ever be. If the startup time becomes a problem, I may explore it, but at that point, it would be because I have a problem I’m trying to solve.

Ideally, as much of the code you write in a rails app should be outside of the requirement of rails (other than, perhaps, activerecord). It’s entirely possible to test most of your code without bringing in Rails, which obviates having to speed up rails booting.

The primary reason to boot rails often, in my experience, is for running tests, and only if you’re testing things that need rails, which, as I mentioned, shouldn’t be all or even most of your code.

Migrations, generators, rails server, etc are run seldom enough that paying a second or two cost for it is fine if it avoids adding things that could trip up developers for large chunks of time, generally much larger than they ever gain.

If, in the course of doing testing, I find that the slowdown is enough that it interrupts the flow of TDD, I would consider trying other tools, but only if I first examine whether or not I’ve delved too deeply into rails land for the particular thing I’m testing, i.e., carefully considered the design.

To @aaronjensen and @masterleep

I could understand your point of view if Bootsnap actually increased complexity, but the fact is, it doesn’t. Yes it hooks into Kernel because there is unfortunately no way around it. But assuming it is properly setup (and it is by default with Rails) it changes absolutely nothing to Ruby’s behaviour. It’s literally free performance.

The problem is that since it’s hooked into Kernel, it very often appear in backtrace and get the blame for unrelated problem. But every time we dig in the reported issues, it’s unrelated to Bootsnap.

Just yesterday I read a blog post complaining about slow boot time in https://github.com/consul/consul, just to see I setup bootsnap, and it made it 3 times faster without having to change a single line of code.

Considering this, I still believe Bootsnap is a good default in rails new, maybe spring isn’t, maybe other parts aren’t. But for a long time we had people complain about boot time, and making Bootsnap a default really makes people life better.

If anything it should be merged into Ruby itself so that it becomes truly invisible.

2 Likes

Isn’t it then just disagreement with Redirecting…? I mean is the problem really with these libraries or is it on the level of principles?

I kind of understand your need to have a specific stack for a specific app. But If you can do that call because you already have the experience then you can skip libraries you don’t want to use. Of course, we could have in Rails a better “interface” for that.

The beginners usually can’t make this call and I am just wondering why it would be better for them to not have something like rich text editor in Rails. Most of the apps I was working on actually had some kind of text input from the users like comments, posts, etc.

Regarding ActionMailbox I’ve never used it, but it doesn’t bother me to have in the tool belt a screwdriver I’ve never used.

1 Like

You and I may have different definitions of the word complexity. It’s hard to look at GitHub - Shopify/bootsnap: Boot large Ruby/Rails apps faster and not see a tremendous amount of complexity. I’m sure it’s a marvelous piece of engineering, and I may very well use it eventually for this project.

One of the hardest problems of computer science is famously cache invalidation. Adding a complex cache to the load process is more complexity. Whether or not it leaks out into day-to-day life is up to the implementation. I’m skeptical, but I don’t have hard evidence at the moment and I don’t necessarily want to experiment on my team when there’s not a very strong need for faster boot performance.

Desire to run only the bits that my application needs. And in the case of the components that introduce routes that I never intend to use, removing them reduces the potential for bugs in those modules to present security vectors.

You’re saying a beginner can’t decide if their app will require a rich text editor? This is a strange statement as it seems to imply a beginner has no idea what they’re going to build. That seems like one of the decisions a beginner would be qualified to make.

When a person needs a rich text editor, they will reach for one. If Rails has a blessed one, they may reach for that first.

I wonder why Rails has such a high boot time without additional machinations like spring and bootsnap? It could be because people don’t mind loading extra code they have no intention of using, just so that they could keep it in their toolbelt.

We don’t have a different definition, we’re just not talking about the same complexity. You are talking about the implementation complexity, I’m talking about the usage complexity.

Since the only difference between an app with Bootsnap enabled and an app without is speed, and that you’re not trading off anything, it doesn’t increase complexity for developers. That’s what I’m saying.

And yes Bootsnap was complex to implement, mostly because Ruby doesn’t offer the proper APIs for it. But the actual concept is super simple.

Adding a complex cache to the load process is more complexity.

That’s the thing, it’s not a complex cache. It simply translate relative paths in absolute paths. That’s all.

I’m skeptical

Yes, I’m not trying to convince you. I just wanted to know what your reasons were, now I know.

1 Like

It’s really the complexity of the runtime environment that I’m concerned with, and consequently increased bug surface area, not any particular complexity to use the gem day to day.

It would be great if these ideas could be merged into Ruby. That sounds like the right place to fix this. If they don’t want to merge them, it would be interesting to know why.

I think something like this is a must!

No, I am saying that for a beginner is hard to evaluate what kind of library they should use. That’s the value of defaults and Omakase, you don’t have to do all these choices.

Get it, thank you! I think it is relevant to what @davetron5000 suggested. I am not sure if the problem is in have the libraries as default or not. It feels for me that it could be more in side effect behavior that these libraries create.

I agree with this entirely. Ghost has this “walk-through” when installing their blogging platform and it would be handy for the rails community.

I’m more interested in easing the enabling/disabling of them, rather than which ones are defaults. I like that this framework is so feature rich to start with. Nice to be able to batten down the hatches as you learn more though.

4 Likes

As an experiment, I started a new rails app to start converting an existing PHP app to Rails. I spent quite a bit of time looking for --skip recommendations to trim things down. Basically, what I wanted was REST API functionality and some boilerplate CRUD forms. My DB is MySQL. Perhaps app trait support inside rails new would help? Instead of listed a bunch of --skip options, specify a --trait option instead.

--trait-minimal - Bare bones with no extras
--trait-rest - REST API app
--trait-full - Everything including the kitchen sink 😉

I think the fact that Rails defaults to installing Bootsnap and Spring falls into the category of “WTF”. It sends a message that Rails is slow, knows it, and has to install more stuff to fix that.

1 Like