00:00:18.539
I was trying to think of what would be a fun thing to do now that we are all back in person again and able to spend time in close quarters.
00:00:23.880
One thing I fell out of love with during the pandemic was traditional conference talks, where I have a whole lot of slides and it's just me talking.
00:00:31.140
These talks don't perform well on YouTube.
00:00:36.420
This time, I thought it would be a lot of fun to have a more interactive session.
00:00:42.780
If this goes really well, then I had a great idea, and Megan did an amazing job helping me.
00:00:55.860
If it doesn't go well, then you all didn't show up and let me down.
00:01:02.160
Without further ado, let's get rolling! A couple of people are still trickling in, but everyone should have a paddle because we'll be doing some voting.
00:01:15.960
Green means you vote for a measure, and red means you vote against it.
00:01:23.100
If you're red-green colorblind, just ask the person next to you how to vote.
00:01:28.799
Let's begin.
00:01:34.740
You may be familiar with a tool called RuboCop; it's a linter and formatter for Ruby.
00:01:43.079
One of the first things I noticed about RuboCop was that it has default configurations that many teams disagree with.
00:01:48.540
Whenever a tool has defaults that people generally disagree with, it leads to custom configurations.
00:01:54.259
When programmers spend too much time in low-priority debates over trivial matters, we call that bike shedding.
00:02:01.439
At Test Double, as consultants, we often see teams pull RuboCop into their workflows only to end up arguing about its rules.
00:02:12.180
Instead of focusing on building their applications, they get caught in these disputes over their random customizations.
00:02:25.680
I've grown frustrated with this because I believe tools should reduce friction and enhance productivity.
00:02:32.400
In 2018, I created a gem called Standard, which you can install through RubyGems.
00:02:43.379
Standard is built on top of RuboCop and includes additional performance-related rules.
00:02:49.860
The special thing about Standard is that it locks down configuration options.
00:02:55.140
If you use Standard, you cannot modify the default settings.
00:03:05.640
A lot of teams started using Standard, and I'm hopeful they shifted their arguments to more important matters.
00:03:11.640
The community has unified to focus on standard practices.
00:03:17.819
Today, in 2023, we're going to create a new gem called Standard Rails, using RuboCop with Rails-specific rules.
00:03:25.800
We're also going to establish a configuration for it here on stage and lock it down to promote consistency across various Rails projects.
00:03:37.200
Unlike my previous approach as the sole decision-maker, this time we'll incorporate democracy by putting everything to a vote.
00:03:42.680
As we go through the rules, you will vote on every aspect.
00:03:48.540
Your participation will help establish important coding conventions.
00:03:54.240
Now, I’ll hand it over to my wonderful co-presenter Megan Waller, who will discuss the ground rules.
00:04:07.620
Let's set the scene—it's all of us against him, deciding on the rules.
00:04:13.920
We'll get through these quickly.
00:04:19.199
Everyone will use their paddle to vote, and I want to see you raise them high so I can see them.
00:04:25.560
Green means you agree, and if you hold up red, that means you are not voting.
00:04:31.920
Let's see everyone's green paddles.
00:04:40.560
Everything looks great.
00:04:45.660
As we think about Standard Rails, we want the rules to be applicable across different types of applications.
00:04:54.240
If someone can use Standard Rails for one project but not another, then we've all failed.
00:05:01.479
We need to focus on rules that direct what developers should and shouldn't do with their applications.
00:05:08.520
This means avoiding rules that mandate specific APIs.
00:05:17.139
As we vote, keep the community in mind and optimize for portability between projects.
00:05:24.840
If there's a built-in ActiveSupport alias that is less portable than a Ruby core method, we prefer the Ruby core method.
00:05:32.100
In cases where the vote is too close to call, we'll disable the rule by default.
00:05:39.960
Any rules enabled by you that we disagree with will have a sponsor read afterward.
00:05:45.960
We have 40 minutes, tons of people here, and four flip charts full of rules—120 rules in total.
00:05:53.820
Let's keep the tempo up to maximize our time.
00:06:01.740
We'll also use these 30-second timers when someone has something to say about a rule.
00:06:09.240
Now let's practice voting again. If you agree and want to be part of this process, raise your paddles to the green side.
00:06:16.380
All right, looking good—let's move on to the main event.
00:06:22.380
I know everyone is excited, but I want to ask you all to keep it polite.
00:06:29.820
We have 120 rules and they’re sorted by spiciness, descending.
00:06:35.640
Here’s the first rule on the list: ActiveSupport aliases.
00:06:42.840
This rule checks that ActiveSupport aliases to core Ruby methods are not used.
00:06:48.099
It means we shouldn't use append and prepend on an array; instead, use the shovel operator and unshift.
00:06:55.140
Interestingly, many built-in Ruby methods began as ActiveSupport aliases before making their way into Ruby.
00:07:05.520
To turn them off seems counterproductive.
00:07:10.680
I'd love to hear opinions on enabling or disabling this rule.
00:07:15.960
Does anyone want to make a case for or against?
00:07:21.960
I see a hand—let's get a microphone to you.
00:07:26.279
I always get confused with unshift, and I have to look up what it does.
00:07:31.380
But append and prepend are easier for me to remember.
00:07:37.800
This is a vote in favor of disabling the rule.
00:07:42.800
Does anyone have a counterargument?
00:07:49.680
Votes are in—raise your paddles!
00:07:55.560
Green if you want it enabled, red if you want it disabled.
00:08:03.480
Okay, the consensus is to disable it.
00:08:10.920
Next, we've got 'create table with timestamps.'
00:08:17.760
This rule mandates that all tables defined in migrations must have the 't.timestamps' field.
00:08:23.280
Anyone want to make a case for or against enabling this rule?
00:08:30.540
Let's get a microphone to you for your comments.
00:08:38.880
There are sometimes append-only tables, so we wouldn't want to have updated at on them.
00:08:44.460
Anyone want to raise a counterargument?
00:08:49.260
Votes ready? Green means you want it enabled; red if you want it disabled.
00:08:56.280
Let's see those paddles! Ok, looks like the vote is to enable it.
00:09:01.740
Now we have 'rails freeze time.' This identifies usage of 'travel to'.
00:09:06.960
If enabled, this cop forces you to use 'freeze time' instead.
00:09:12.840
Does anyone have thoughts on enabling this rule?
00:09:19.860
I hear a strong opinion against enabling this.
00:09:26.220
Let's get ready to vote on this. If you want it enabled, raise green; if disabled, raise red.
00:09:31.740
Looks like the A's have it—let's move on to HTTP status.
00:09:38.160
This rule will enforce the use of symbolic names for HTTP status codes.
00:09:44.040
If you think it should be enabled at all, raise your green paddles.
00:09:50.520
Now, we'll vote on whether it should enforce style for symbols or numerical codes.
00:09:57.180
Green for symbolic, red for numeric.
00:10:06.120
The result is a decision to enable it.
00:10:11.040
Now we have 'three-state boolean column,' which enforces that any new boolean column must have a default.
00:10:16.740
Does anyone want to speak about enabling it?
00:10:22.680
What happens in a codebase with many large tables?
00:10:28.800
Votes ready? Green to enable, red to disable. Let’s see them!
00:10:36.960
The Nays have it, and we move on to 'rails blank' which checks for simpler conditionals.
00:10:43.299
If enabled, it will force you to use blank instead of nil or present.
00:10:49.080
Let’s vote on enabling this rule—green means enable, red means disable.
00:10:54.840
Looks like the yays have it.
00:11:01.920
Now on to 'environment variable access.' This would prevent usage of environment variables in all caps.
00:11:07.800
We’d need to use Rails.application.secrets instead.
00:11:13.560
Let's discuss enabling or disabling this rule.
00:11:20.160
Remember, if you vote yes, that means you won't be using environment variables in all caps.
00:11:26.700
Votes ready? Raise paddles!
00:11:33.420
The vote is in, and the A's have it.
00:11:39.480
We’re moving on to 'application controller.' This requires all controllers to subclass the application controller.
00:11:46.080
The argument is that if you want to decouple application logic, you might consider using ActionController::Base instead.
00:11:53.899
Let’s vote if this one should be enabled or disabled.
00:12:01.920
The A's have it again; congratulations!
00:12:06.960
Now onto 'dynamic ad insertion,' which connects to a GitHub organization for standard RB.
00:12:12.120
If you want to bring Standard to new libraries, let us know.
00:12:18.720
Now, we’ll lightning round through the next few rules.
00:12:26.720
Application Job should extend from Application Job—raise green for enable and red for disable!
00:12:33.120
This one passes easily!
00:12:38.280
Now we have application mailer. Yay has it!
00:12:46.320
And for application record, we’re good with that too.
00:12:53.040
Next up is 'belongs to,' looking for required associations via deprecated options.
00:12:58.680
We want to ensure the rules are relevant for all Rails versions.
00:13:05.640
Let’s see those paddles—A's have it.
00:13:11.880
Redundant presence validations on 'belongs to'—this checks for automatic validations.
00:13:17.280
Votes! Green to enable; red to disable.
00:13:23.640
Decisive vote—yays again.
00:13:29.880
Moving to 'action controller test case,'—no more controller tests.
00:13:35.280
If you strongly oppose, now’s your chance to voice it before we vote.
00:13:46.320
Votes ready? Green for enable, red for disable.
00:13:52.080
This one passes; we nixed the old controller tests.
00:13:58.320
Lastly, we have 'active record override,' checking for overriding built-in methods.
00:14:03.360
Let’s see votes on this one: do you agree with the rules?
00:14:09.480
The yays have it—we’re enabling this rule.
00:14:15.840
Finally, we have the 'rails date' rule, which keeps track of time zones.
00:14:22.560
Raise green to enable, red to disable.
00:14:28.920
The rule is enabled, and we're in favor of keeping it strict!
00:14:37.560
We're coming up on time, so let’s act quickly.
00:14:48.840
This is our lightning round—no arguments, just votes.
00:14:56.820
First, we can't write 'not equals' in queries.
00:15:01.740
Paddles up if you want to enable this rule.
00:15:07.680
Yays have it!
00:15:15.840
Next, we have 'unique before pluck.' Raise your paddles!
00:15:24.360
The consensus is to enable it; wonderful job!
00:15:30.720
Next up: 'time zone assignment.' If you agree with the block usage, paddles up now.
00:15:46.620
We’ve now got 'strip your doc,' and it requires using the new squiggly strip.
00:15:52.920
Everyone is in favor; let’s keep going!
00:15:58.560
Next: 'scope arguments.' Paddles up if you want to enable!
00:16:03.960
Unanimous decision to enable. Great work!
00:16:10.560
Now, we’ll discuss 'safe navigation with blank.' Please raise paddles to vote.
00:16:18.480
A's have it again.
00:16:26.160
Lastly, our very last voting—'convert tri non-bang.'
00:16:31.320
Votes ready, paddles up!
00:16:36.720
This doesn't get enabled.
00:16:41.800
We appreciate your patience through this experiment.
00:16:46.920
Feel free to bring your paddles to meetings!
00:16:54.820
You can now run 'gem install standard rails' for a preview edition.
00:17:02.540
Thank you all!