Transcript

Can a room of developers reach a consensus on the minutiae of syntax and formatting for a Rails project?

We asked the attendees at this town hall-style RailsConf 2023 session to perform that seemingly impossible feat … and it went kinda okay!

As you’ll see in this video of the talk, we laid the groundwork for Standard Ruby’s first plugin: standard-rails. Our goal? To crowdsource the toughest debates once and for all, saving your (and every other) team the time of having to do it all over again.

We started by sorting the rubocop-rails rules in descending order of spicyness ("🌶️ desc"), gave a high-level overview of each rule, solicited arguments from the attendees, and then held a vote over whether to enable or disable the rule.

To keep things interesting, there were lots of props, playful heckling, and increasingly-spiteful consequences for votes that we as presenters didn’t agree with. To keep the tempo up, we threatened the audience with the knowledge that every rule that gets a vote is one fewer rule that Justin gets final say over—it proved to be a powerful motivator!

We voted on the following rules during the session. Feel free to peruse these or just install standard-rails yourself and give it a go!

Rule Name Vote Result
Rails/ActionControllerTestCase Disabled
Rails/ActionOrder Disabled
Rails/ActiveRecordOverride Enabled
Rails/ActiveSupportAliases Disabled
Rails/ApplicationController Enabled
Rails/ApplicationJob Enabled
Rails/ApplicationMailer Enabled
Rails/ApplicationRecord Enabled
Rails/BelongsTo Enabled
Rails/Blank Enabled
Rails/CreateTableWithTimestamps Enabled
Rails/Date Enabled
Rails/EnvironmentVariableAccess Enabled
Rails/FreezeTime Disabled
Rails/HttpStatus Disabled
Rails/RedundantPresenceValidationOnBelongsTo Enabled
Rails/SafeNavigation Enabled
Rails/SafeNavigationWithBlank Enabled
Rails/ScopeArgs Enabled
Rails/StripHeredoc Enabled
Rails/ThreeStateBooleanColumn Enabled
Rails/TimeZoneAssignment Enabled
Rails/TopLevelHashWithIndifferentAccess Disabled
Rails/UniqBeforePluck Enabled
Rails/UnusedIgnoredColumns Enabled
Rails/WhereMissing Enabled
Rails/WhereNot Enabled
00:01
So order, order.
00:05
I was trying to think of what would be a fun thing to do,
00:10
now that we are all back in person again
00:14
and able to spend time in close quarters.
00:18
And I thought one thing I fell out of love with
00:21
during the pandemic was traditional conference talks
00:24
where I have a whole lot of slides
00:26
and it's just me blasting at you
00:28
because those don't perform well on YouTube.
00:32
And so this time, I thought it would be a lot of fun
00:35
if we had a more interactive session.
00:38
And so this is going to really,
00:40
if this goes really, really well, then I had a great idea
00:43
and Meagan did an amazing job helping me.
00:46
And if this goes really poorly, you all didn't show up.
00:49
(all laughing)
00:51
And if anything, you let me down.
00:54
So without further ado, let's get rolling,
00:59
a couple people are still trickling in.
01:03
Everyone should have a paddle
01:04
'cause we're going to be doing some voting.
01:07
Green means you vote for a measure
01:10
and red means you vote against a measure.
01:12
And if you're red green colorblind,
01:14
just ask the person next to you how you're voting.
01:20
All right, let's begin.
01:24
So you may be familiar with a tool called RuboCop.
01:28
It is a linter and a formatter for Ruby.
01:32
One of the things that I first noticed about RuboCop
01:36
was it has default configurations of how it wants you
01:40
to use your Ruby that a lot of teams disagree with.
01:43
And whenever a tool has defaults
01:46
that people generally disagree with,
01:47
it means everyone goes and configures them.
01:50
Whenever programmers spend a lot of time
01:52
on a low priority argument or debate
01:56
about something that doesn't really matter very much
01:58
or is certainly lower priority than building the thing
02:00
that they've been tasked with doing,
02:02
we tend to call that bike shedding,
02:04
like arguing over the color of the bike shed
02:08
at a nuclear power plant is like really low on the list
02:10
and yet it really works us up
02:11
and you get in fights about it.
02:14
And at Test Double, we're consultants,
02:16
so we see a lot of teams
02:17
and we just saw this pattern repeat over and over again,
02:19
where you go to a team and then you see them pull
02:22
in RuboCop and then they get in a big fight about it.
02:24
And what ends up is they have their own kind of custom,
02:26
bespoke RuboCop preference.
02:29
Then I go to another team, same thing happens,
02:31
I go to another team, same thing happens.
02:32
And what's actually emerging from each of these teams
02:34
isn't that they use RuboCop,
02:36
it's that they're using RuboCop as a framework
02:38
for having stupid arguments.
02:41
And I got really frustrated with this
02:44
because I firmly believe that tools should reduce friction
02:47
and make it easier to do our jobs and focus on what matters.
02:49
That's why we use Rails after all.
02:51
That's what that was all about.
02:53
And so back in 2018,
02:54
I created a gem called Standard Ruby.
02:57
You can go and gem install it.
02:59
And what Standard is,
03:01
is it simply depends on RuboCop,
03:03
as well as RuboCop performance,
03:05
some additional performance related rules.
03:07
And it's got a configuration in it,
03:10
it just preconfigures everything in one way.
03:13
But the special thing about Standard
03:14
is that it locks it down.
03:16
So if you use Standard,
03:17
you cannot go and futz with and change and bike shed
03:19
these configuration options, you're just stuck with it.
03:23
And so now a whole lot of teams just started using Standard
03:25
and hopefully they're arguing about more important nonsense.
03:30
And I've been really happy with just seeing
03:32
how the community has shown up to pull all those bike sheds
03:36
into the standard repo and so we can have
03:38
one last bike shed to rule them all.
03:42
Today, 2023, here's what we're going to do.
03:45
We're going to create a new gem called Standard Rails.
03:47
And it's going to look a lot like the first go around,
03:50
where we're depending here on a RuboCop extension
03:53
called RuboCop Rails, a lot of Rails specific rules.
03:56
We're going to establish a configuration for it
03:59
here on stage, and then we're going to lock it down
04:01
so that we can all adopt Standard Rails
04:03
and have more consistency
04:04
between our different Rails projects.
04:06
There's just going to be one difference
04:07
where with the Standard,
04:09
I came in, made my own configuration,
04:11
and then the whole internet got mad at me
04:14
and they argued with me.
04:15
So, I was benevolent dictator for life and I don't,
04:20
that role doesn't suit me as well as some people
04:22
in our community.
04:24
So this time around, (audience laughing)
04:27
we're going to give democracy one last chance
04:31
and put everything to a vote.
04:33
And so here's Standard Rails,
04:35
you'll vote on everything and then that's you right there.
04:37
And then, so everyone can get mad at you.
04:39
(audience laughing)
04:41
So, what I'm doing here is I'm optimizing
04:45
for developer happiness, where I'm the developer
04:48
and it's my happiness that I'm optimizing for.
04:52
And so now you know the basic goal of the day,
04:57
I'm going to hand it over now to my wonderful co-presenter,
04:59
Meagan Waller, and she's going to discuss the ground rules.
05:03
All right.
05:05
Let's sort of like just set the scene here.
05:07
It's all of us against him.
05:09
The rules that we don't get to,
05:10
he's going to get to decide on.
05:12
So let's get through these quickly.
05:15
All right, so ground rules that we have here are.
05:20
Okay, we thought she'd be able
05:24
to see the screen a little bit.
05:26
All right, so you're going to use your paddle to vote.
05:27
I want everyone to be able to raise their paddle high
05:29
so I can see it.
05:32
Green means you agree.
05:33
So if you are putting up red,
05:35
you're saying you're not voting.
05:37
Let's see everyone's green paddles.
05:41
Okay, it's looking pretty good. That looks great.
05:46
So the way that we're sort of thinking about Standard Rails
05:50
and when we're thinking about the things that we do want
05:52
to turn on, these rules should make sense
05:55
when they're applied to pretty much any type of application.
05:58
And so, if someone is using Standard Rails for one project
06:01
and they're not able to use it for another,
06:03
then like we all have failed.
06:05
So we also are going to look out for rules
06:09
that tell people what they should do with their apps
06:12
or what they shouldn't do with their apps.
06:13
So like restricting aliases, things like that,
06:17
instead of like just mandating specific APIs.
06:19
So keep that in mind as we're voting.
06:21
It's not just,
06:23
I guess it's not just like the things
06:24
that are like your little pets,
06:27
favorite rules that you want to have enabled.
06:29
Let's keep the whole community in mind
06:31
as we vote on these rules.
06:33
And we really would like to try
06:37
and optimize for portability.
06:39
So if there's a built-in that would prefer that you use,
06:44
Active Support alias versus a Ruby core method,
06:47
be more portable for us to be able
06:48
to use the Ruby core method.
06:51
So if a vote is too close to call,
06:53
that's telling us that there's probably
06:55
too much tension between it, it's kind of divisive,
06:59
so we're just going to disable it.
07:01
That will be the default option there,
07:05
when it's like a photo finish kind of vote.
07:09
And any rule that gets enabled by you all
07:13
that we disagree with,
07:16
you will have a little sponsor read from us
07:19
now that the bird app's not really a place where we can go
07:21
to air our grievances.
07:22
So that's what's in store for you all.
07:27
So we have 40 minutes,
07:28
we have tons of people here
07:31
and we have four of these flip charts
07:37
with 30 pages each full of rules.
07:38
It's 120 rules for those of you keeping score at home.
07:42
So let's keep the tempo up.
07:43
In order to maximize the amount of time,
07:47
I also have these 30 second sand timers. Wow, okay.
07:55
We'll be using these when we hand the mic to anyone
07:58
who might have a thing to say about a rule,
08:01
you'll have 30 seconds to say what you want to say.
08:05
Alright, so let's do another practice vote,
08:08
now that we have all the ground rules established.
08:11
If you agree and you want to vote
08:13
and you want to be a part of this process,
08:15
let's raise your paddles up to the green side.
08:20
All right, looking good, let's go.
08:22
The yeas have it.
08:24
All right, so now on to the main event.
08:27
So, it's the end of the conference.
08:29
I know that everyone's really, really excited
08:31
and the energy's really super high.
08:32
But I'm going to ask you all just to chill a little bit
08:35
and we're going to do this politely.
08:38
And because there's 120 rules,
08:40
we have presorted it for you in spiciness descending.
08:44
So we've picked out some of our favorites
08:48
that we think are going to lead to some interesting discussion.
08:51
Here's the first on the list, Active Support aliases.
08:55
So what this rule does is it checks
08:57
that Active Support aliases to core Ruby methods
09:00
are not used.
09:02
Meaning like, don't use append and prepend on array
09:06
when those are Active Support methods,
09:09
instead use the shovel operator and unshift.
09:13
Now one of the funny things if you've been doing Rails
09:15
for a long time is lots of built-in Standard Ruby methods
09:19
started off as Active Support custom aliases
09:23
and then found their way into Ruby.
09:26
So to just turn them off is kind of cutting off that path.
09:32
So I've just shared my bias.
09:34
In terms of like how we're going to conduct each of these,
09:38
we'd love to give somebody from the audience
09:41
a chance to make a case for or against
09:43
enabling a particular rule.
09:46
And then if somebody has something else
09:48
to say that's a rebuttal,
09:49
we'll give somebody else 30 seconds, their equal time,
09:51
to make a counter case.
09:53
Does anyone here want to make a case
09:55
for or against enabling Active Support aliases?
10:05
Somebody's got a hand up.
10:07
We're going to bring a microphone to you, so everyone can hear.
10:17
I always get confused with unshift
10:20
and I always have to look it up,
10:21
like what the crap is this doing again?
10:24
But append prepend just clicks in my brain.
10:27
All right, so this is a vote in favor
10:29
of not enabling the rule, disabling the rule.
10:33
Okay, anyone want to raise a counter argument?
10:38
No. All right, let's go vote.
10:39
All right, let's vote.
10:41
All right, raise your paddles to green
10:45
if you want it enabled.
10:46
Raise it to red if you want it disabled.
10:49
(indistinct from audience)
10:49
Yes.
10:50
(indistinct from audience)
10:52
Enabling prevents the use.
10:54
(audience speaking) This is where they get you!
10:56
Yes.
10:57
A lot of rules are written this way
11:01
and this is why we we're here to put in the work.
11:04
(audience laughing)
11:08
So, okay, ballots up.
11:12
The nays have it.
11:13
The nays have it.
11:15
(audience laughing)
11:20
Disable.
11:21
All right, so next up.
11:24
We've got create table with timestamps.
11:26
So here it's saying if we enable this rule,
11:29
all tables that you define in your migrations
11:32
must have the t.timestamps,
11:34
so the create at and updated at columns must be defined,
11:37
unless it looks like a joiner table
11:39
of just these different IDs.
11:42
Anyone want to make an argument in favor or opposed?
11:48
(indistinct from audience)
11:50
Okay, we're going to get the microphone to you so you can.
11:57
One more time for the video.
11:59
There are sometimes append only tables,
12:01
so we don't want to have updated at on them.
12:03
Append only tables, so you don't want to have updated at
12:06
'cause they're never updated.
12:06
Got it. Okay.
12:08
Anyone want to, so that's an argument then in favor
12:10
of enabling it or wait no, of not enabling it.
12:13
(audience laughing)
12:15
See, you got my back.
12:17
Okay. Aaron.
12:24
Cathy's getting her steps in.
12:25
I think like nearly all tables
12:27
would want to have timestamps.
12:28
So if you want to disable it on a,
12:31
if you have append only, you could just do it for that one.
12:34
Yes, there's a real special case.
12:36
There is a standard disabled comment directive,
12:40
so that's okay.
12:41
Doesn't mean a thousand percent of the time just,
12:44
you know, it's the golden half.
12:45
All right.
12:46
All right. We heard our argument.
12:51
Again, should have seen this coming.
12:54
Really, we should've.
12:55
Green means you want to enable this rule,
12:58
and what this rule will do is force you to use t.timestamps.
13:03
Ballots up.
13:05
All right.
13:06
- All right. The yeas have it. Enabled.
13:10
(audience applauding)
13:12
See, just four or five more hours and we're going to be.
13:18
(audience laughing)
13:21
Through this thing. All right?
13:22
I hope you don't have any flights tonight.
13:24
All right, so Rails freeze time.
13:27
This identifies usage of travel to,
13:30
which time travels not the system clock,
13:33
but Ruby's idea of what the system clock is
13:36
with an argument of the current time.
13:39
And then if enabled,
13:41
this cop forces you to use freeze time instead.
13:46
Anyone want to chime in?
13:48
We had a very emphatic raise back here.
13:53
Did you have a comment in the red back here?
14:02
I don't see a good reason
14:04
not to enable it, freeze time makes sense.
14:09
Traveling time, there's a variety of different arguments.
14:11
Takes more brain cycles.
14:14
Okay, so freeze time's better.
14:16
Anyone have an opposing?
14:18
Behind you, somebody's got a disagreement.
14:21
Having built a time and labor system,
14:24
you got to use travel time.
14:29
Okay, because freeze time actually stops the clock,
14:33
travel_to will move the clock to a time
14:36
and then keep the clock running.
14:39
(audience groaning)
14:41
Yeah, okay, I get it.
14:45
Okay, let's take those words and put 'em in our ballots.
14:49
Let's, yeah, so red, okay, you all get it.
14:57
The nays have it.
15:00
All right, moving right along, Http Status.
15:03
This will, by default if enabled,
15:05
it'll enforce the use of the symbolic shortcuts or names
15:11
for any sort of head status code
15:14
that you want to send in your controller.
15:16
Meaning like, symbol not found as opposed to 404.
15:20
Or we could enable it and then enforce the exact opposite
15:23
and say, no, you have to type 404,
15:25
you may not put the symbol not found.
15:27
So for rules like these that have options,
15:30
we have a two-tiered voting system.
15:33
(audience laughing)
15:35
Because it was too expensive to make triangular cut outs.
15:40
So first up, if you think this should be enabled at all,
15:45
either way, green.
15:49
Let's try that first.
15:50
So everyone vote, either enable or disable right now,
15:54
regardless of what the setting is,
15:56
then we'll vote on the setting second.
16:00
So green, so people are voting in favor of consistency.
16:03
So the yeas have it, we're going to enable it.
16:05
Now some of you're going to get mad though.
16:07
(audience laughing)
16:08
If you don't get your way.
16:10
You see now, like if nothing else,
16:12
I hope I'm building empathy for how much this job sucks.
16:16
Okay, so now we're going to do a second vote
16:19
for enforced style, right?
16:20
Yep.
16:21
So we have symbol or numeric, right?
16:24
Those are the two styles?
16:25
Okay? So which color should be which?
16:27
Okay, let's do green for symbol, red for numeric.
16:31
All right, ballots up.
16:35
Oh wait, do we want to have an argument?
16:37
We didn't have an argument.
16:40
I didn't give a chance to give the argument. Hold on.
16:42
Eileen wants to speak. Let's give her the microphone.
16:52
Do people actually use this?
16:54
This is bonkers. It's the same number of characters.
16:57
It doesn't make your code better.
16:59
I hate both.
17:00
There shouldn't be a choice.
17:02
This should be disabled.
17:03
(audience laughing)
17:08
Eileen missed the boat.
17:12
Okay, anyone have a comment about,
17:16
we'll take one comment on symbolic versus numeric.
17:21
And Cathy keeps picking the people furthest away from her.
17:24
I'm not picking, they're doing it.
17:29
If I'm searching the code base,
17:31
it's easier to search for the numeric codes than words
17:34
that also are used all over the place.
17:36
And I have to look up all of these anyway,
17:38
so numbers.
17:40
(audience applauding)
17:41
All right, okay, let's not get carried away
17:44
in this sort of populist law fervor.
17:49
Call a vote?
17:50
Yeah, let's vote.
17:51
Alright, green for symbols, red for numeric.
18:00
Wow.
18:00
All right, so the left side of the room is mostly green
18:03
and the right is most.
18:04
I don't like this.
18:06
Does that mean we get to disable it?
18:07
Do we get to disable it?
18:09
This is too close to call
18:11
and therefore the rule is disabled.
18:13
(audience cheering)
18:18
(audience indistinctly talking and laughing)
18:24
Yeah, not unrelated,
18:27
Eileen has my phone number and can text me anytime
18:29
when she's not happy.
18:33
All right, next one we got here
18:34
is the three state boolean column.
18:39
What this refers to is,
18:41
when enabled, it enforces that any new boolean column
18:44
that you add in the migration
18:46
must have a default setting and must be not nullable.
18:49
Meaning that the column's value is either always false
18:52
or true, but never null.
18:56
Steven would like to chime in.
19:03
This is terrible in any code base
19:05
with a very large table or a number of very large tables
19:08
because you can't like, safely doing this is hard.
19:11
So more clearly you want to not enable this.
19:14
I want this disabled, yes.
19:15
You want this disabled
19:16
because if you have a large table, it's bad.
19:19
I can't, yes.
19:21
Wait, what does disabled mean again in this case?
19:23
(audience laughing)
19:28
Okay, so here's a way to look at it everyone.
19:30
If we disable all the rules,
19:33
then it's like this just homeopathic thing
19:35
that prevents us from having any constraints
19:38
on how we write our code.
19:40
So disabling everything means like we're allowed
19:42
to do whatever we want.
19:44
Enabling things disallows us from doing something.
19:46
And in this case that something is nullable boolean columns.
19:51
So if you enable it,
19:53
you can't make a nullable boolean column.
19:57
And he wants nullable boolean columns,
19:59
which means he does not want to enable it
20:04
because defaults are expensive on large tables.
20:06
There we go.
20:08
Any counterarguments?
20:10
Hey Aaron. Oh, here we go, Landon.
20:12
I think it's frustrating the other way
20:14
because it's like like developers are lazy
20:17
and like they won't set a true or false
20:19
and you have a null and you don't know what it is
20:21
or something will happen
20:22
and you're looking at the database later to debug something
20:24
and you're confused.
20:28
Okay, so.
20:31
Are we feeling like we're ready to vote
20:33
with all this information?
20:35
All right, enabled is green, disabled is red.
20:41
Let's vote.
20:43
Oh wow, this is close.
20:45
There's some late breaking nays.
20:48
I don't know, I think the yeas have it.
20:49
The yeas have it.
20:51
(audience applauding)
20:54
And Steven accidentally voted yes.
20:58
(all laughing)
20:59
He's just catching that now.
21:04
No one to blame but yourself.
21:06
All right, Rails Blank.
21:12
This rule checks for code that can be written
21:14
with simpler conditionals using object blank
21:16
defined by Active Support
21:18
as opposed to like nil or empty or present.
21:23
So, let's get some comments.
21:26
Yeah. Anyone have anything to say about this one?
21:33
I think everyone's still working out the algebra.
21:35
Yeah, yeah.
21:38
If enabled it will force you to use blank
21:40
whenever blank would be terser.
21:43
Blank is defined in Active Support.
21:46
Nil and empty are defined in Ruby.
21:51
Noel's got a comment, point of order.
21:55
(audience member indistinctly speaking)
22:00
Blank is defined inactive report in terms of empty
22:02
on whatever the Ruby object is.
22:04
Yeah, so just blank
22:05
is so you can get some unexpected behavior from blank.
22:10
Not a pro or a con, just a point of order here
22:13
that blank is defined in terms of empty on its object.
22:17
Noel, author of many books, says that it's not a pro
22:20
or a con to have unexpected behavior from your computer.
22:23
(audience laughing)
22:27
I'm in favor of this one
22:32
'cause I'm trying to be more present.
22:34
(audience laughing and applauding)
22:38
All right, so on one hand your Ruby code is less portable,
22:42
but on the other hand you made a pun.
22:43
Yeah.
22:46
All right, let's vote.
22:49
Green, the yeas definitely have this.
22:51
Ah, the yeas definitely have it.
22:54
Oh, fun story. Meagan and I disagree with you all.
22:57
So now you get your first sponsor read.
23:01
All right. Is this for the newsletter?
23:03
Yes.
23:04
All right.
23:06
"You've Got Mail" isn't just a 1998 classic by Nora Ephron,
23:10
it's your reality when you sign up
23:12
for the Test Double newsletter.
23:14
(audience laughing)
23:16
Get updates, insights, expert tips,
23:18
and more from our Test Double double agents.
23:21
Sign up today at TestDouble.com/newsletter.
23:24
(audience applauding)
23:31
The panic on my face is that I realized that we split up
23:34
the sponsor reads, but she prepared way more for this.
23:37
(audience laughing)
23:39
Lower your expectations for when it's my turn.
23:42
Next up, environment variable access.
23:47
Wait a second, we enabled the last one, right?
23:50
There's a whole bunch of options inside of this one.
23:54
I don't care.
23:55
We're just going to enable it all.
23:56
You were that enthusiastic.
23:57
(audience laughing)
23:59
We'll fix it in 0.1.
24:03
Environment variable access,
24:05
what this would do is prevent you
24:06
from using the environment, all caps ENV cache,
24:14
to hash like thing to reference
24:16
and write environment variables.
24:18
Instead, you'd have to use Rails application secrets
24:21
or config to read and write them.
24:24
Any comment?
24:27
Anyone want to chime in? Don't be shy.
24:35
Voting yes means you can't do it, yes.
24:38
That's the theme of the.
24:42
This is why RuboCop is so popular.
24:46
No comment?
24:47
Oh, we got one over here.
24:53
Yeah. What about if we don't.
24:55
So I'd vote against, not enabling this.
25:00
I think I got that right.
25:01
If we don't use secrets
25:02
or if we don't want to store anything sensitive in config.
25:06
Then you would want to disable this rule.
25:08
If if you want to be able to use ENV,
25:10
then you'd just vote to disable it.
25:12
Okay, so I think that might be, but.
25:16
The person behind you, may have a follow up.
25:20
Actually I'm just unclear
25:21
what we're gaining by this
25:22
since they can just do Rails.application.secrets
25:25
and then write or read.
25:28
Are we just making them think more about it
25:30
since they have to write more code?
25:32
I don't know.
25:34
Kevin, you want to, looks like Kevin's got a comment.
25:39
So I believe the advantage of this
25:41
is that you discover an error
25:43
due to a missing environment variable at boot time
25:46
instead of while the application is running.
25:48
So if you're missing this environment variable,
25:51
you're forcing it to be in Rails application secrets,
25:53
which gets populated at boot time.
25:55
That will cause an error immediately
25:57
instead of waiting for some point
25:58
when the application is running.
25:59
Oh. Knowing murmurs.
26:05
All right, with that in mind, let's vote.
26:12
Oh, I'd say this is 60-40 green red.
26:15
Yeah.
26:17
Yeas have it.
26:18
Yeah.
26:19
(audience laughing)
26:22
Very tepid response.
26:23
Well, we disagree again, so I don't like that one.
26:27
So I'm going to go to the next sponsor read.
26:29
All right, so we're doing,
26:32
well, I'm doing something funny.
26:33
I'm going to Japan next month
26:36
for what was going to be a vacation,
26:37
but then RubyKaigi got scheduled at the same time.
26:39
So now I'm going to RubyKaigi and I'm not speaking,
26:41
I'm just going to go there
26:42
and I'm going to do kind of like a travel blog
26:44
of like ramen pictures and travel tips
26:47
and also see Ruby internals.
26:51
And so I'm going to be live blogging at Test Double's blog.
26:55
We'll set something up and if you're interested
26:57
in kind of getting an inside scoop of what's coming
27:01
in Ruby 3.3 and what are the 3.2 enhancements
27:04
that we're already benefiting from and how they work,
27:06
there's going to be a lot of really cool technical talks there
27:08
and I'm going to try to do a better job of covering those
27:10
for our Western audience.
27:11
'Cause normally the stuff that goes on at Kaigi
27:13
doesn't get talked about very much,
27:14
even though it's like literally the future of our language.
27:17
So if you're interested, just check out TestDouble.com/field
27:22
and you can sign up and you'll get notified
27:24
when the live blog goes up in the middle of May.
27:28
Thanks, Thomas.
27:31
He's the real hero.
27:32
That was nowhere near as good as her reads.
27:36
Next up, application controller.
27:38
This one requires that all of your controllers
27:42
subclass the application local application controller
27:46
that's generated for you when you start with.
27:49
Comments.
27:53
And I've bundled up like five of these.
27:55
There's like five rules just like this.
27:56
So after we do this one,
27:57
we're going to do a speed round on the subsequent ones.
28:00
Just learned today
28:01
from the Rails engines talk
28:03
that if you want to decouple your application logic
28:06
from your engine, you can do action controller base
28:10
instead of doing application controller,
28:12
so that would be an argument for disabling this.
28:15
Thank you.
28:15
You see, now there was a comment where somebody said
28:18
to disable or enable as part of their argument
28:20
and it was much clearer.
28:21
(audience laughing)
28:23
Just a point of order.
28:25
The explanation given on the previous one on what gain
28:28
this is giving us is helpful in general,
28:30
so if we could have someone provide a,
28:33
Hey, this is why it'd be a good idea as a part of going in,
28:35
that might help the dialogue.
28:37
Yes, feel free to offer those whenever you'd like.
28:40
(audience laughing) Aaron.
28:44
So I like this particular rule
28:46
because we can put application specific stuff
28:49
in our application controller.
28:51
That application controller constant is controlled
28:53
by your application versus action controller base,
28:57
which is owned by Rails.
28:58
So you would want put any common methods
29:01
in the application controller
29:03
versus monkey patching Rails, which we all know is bad.
29:12
Let's have one last from Brittany.
29:14
I just want to clarify that in the off chance
29:16
that you want to do that thing that he said before,
29:19
you can just comment out this rule, right?
29:22
In the one random case that you want to.
29:25
Yes you can.
29:25
Okay, cool.
29:26
Yeah, just just so you know, you don't have to vote no
29:29
just so you can do some crazy shit.
29:30
(audience laughing)
29:35
All right, let's vote.
29:40
All right. Yeas have it.
29:45
All right, well, congratulations
29:47
'cause this is another sponsor read
29:49
'cause I don't like this one.
29:55
Too many ads. Yeah, right.
29:57
Dynamic ad insertion. All right, this one's on Meagan.
30:02
All right.
30:03
So, we officially have a GitHub organization
30:07
for standardrb.
30:08
All of our officially sanctioned standard plugins
30:11
are going to live here.
30:13
If you're excited about bringing Standard to a new library,
30:16
we're excited as well
30:18
but please don't use names like Standard-Rspec
30:22
without talking with us first,
30:23
and we can work together to get those things going.
30:27
So just check out our GitHub.org
30:29
to get involved in any new standard plugins
30:32
that are coming out in the future.
30:34
All right, thank you very much for that.
30:36
Okay, so like I said, this is going to be a lightning round.
30:38
We're just going to vote on the next four or five.
30:41
I vote for chaos.
30:43
I think we should just alternate whether we support.
30:46
So application job,
30:48
should they extend from application job or from.
30:52
All right. The yeas have it.
30:56
Does that mean another sponsor read?
30:57
Yeah.
30:58
Then no, no, no, no, no, no, no, no.
31:00
Okay. Application mailer.
31:03
All right.
31:04
Yeas have it.
31:05
Application record.
31:07
Yep. Yep.
31:08
You don't have to raise your arms higher every time.
31:11
(audience laughing)
31:12
We get it.
31:13
I get it. I don't know how multi database support works,
31:20
but Eileen wrote that, so she knows.
31:24
If you inherit from active record base,
31:26
you will break multi database support.
31:29
So that's probably a vote in favor of the rule.
31:35
Next up, belongs to.
31:38
Look for belongs to associations where we control
31:42
whether the association is required
31:44
via the deprecated required option
31:47
instead of apparently some cutoff text,
31:50
instead of optional true.
31:51
So like before Rails 6.1 or whatever,
31:55
when you did belongs to association definition,
31:59
it was optional by default.
32:01
And it has since become required by default.
32:03
So you can say belongs to blog required.
32:10
Good grief.
32:11
Optional true. (audience laughing)
32:16
Look at the good and the bad code example.
32:18
(audience laughing)
32:19
And you kind of get it.
32:20
It's the last day.
32:21
All right.
32:23
Ali's got a comment.
32:24
We're not voting yet.
32:26
Let's see.
32:28
Ali, save me.
32:32
Well, I just have a question.
32:33
What happens if you're on an old version of Rails
32:35
that doesn't do the optional thing?
32:36
Right?
32:37
So the RuboCop Rails will detect the Rails version
32:43
by looking at the gem file, or there's also,
32:46
you can specify it in an option
32:48
and if the rule is not relevant to that option
32:51
or that version of Rails yet, it will disable itself.
32:58
Someone back here.
33:01
All right.
33:05
Okay, would it be good practice
33:06
to just have belongs to blog
33:08
and leave out required or optional
33:11
since it's defaulted to be required.
33:14
It would've been a good idea to maybe make this one rule
33:16
with four configuration settings,
33:18
but there's like four scattered throughout RuboCop Rails,
33:20
so here we are.
33:22
All right.
33:23
I think we should probably just put it to a vote.
33:25
Yeah, let's vote.
33:29
All right.
33:31
The yeas have it.
33:31
You see, so I don't know how about you,
33:34
but decision fatigue tends to build up towards the end
33:37
of the day and you started just like anything
33:40
to get out of here.
33:41
Okay, sure, I'll.
33:42
(audience laughing)
33:45
Redundant presence validations on belongs to,
33:48
so this one's similar
33:50
because now the valid.
33:55
Because by default belongs tos are required.
33:59
Like there's a validation that happens automatically
34:02
by a default, that they be set.
34:04
If you also say, I validate the presence of that thing,
34:07
if enabled this rule will be violated.
34:11
And you'll have to delete the validates user presence
34:13
'cause it'll be redundant.
34:16
People are to vote.
34:17
We're voting. We're voting. All right.
34:19
Very decisive bunch here.
34:21
See. You guys are taking over.
34:23
I feel better about you all taking the blame
34:26
for however this goes.
34:28
Ready and eager.
34:30
Next up, action controller test case.
34:34
This one, you may recall that in Rails 5,
34:37
controller tests were deprecated
34:40
and instead integration tests
34:45
were the preferred alternative.
34:47
We're now at Rails 7, which is two Rails' later
34:50
and if enabled, this rule would say,
34:53
Hey, no more controller test.
34:54
It'll actually trigger a violation
34:55
for every controller test.
34:59
Anyone have a comment about whether or not?
35:01
Who feels strongly about this?
35:06
Okay, so somebody shouted impolitely,
35:10
but audibly, that it's going to be a huge.
35:15
In favor of disabling.
35:18
This is just going to make a huge amount of noise
35:20
if you run it on, try to adopt this in a code base
35:23
that wasn't already using this rule.
35:26
That's true.
35:29
And not easy and quick to change either,
35:31
it's not just like switch some syntax,
35:33
it's rewrite your tests.
35:36
Any strong counter arguments?
35:38
RSpec.
35:39
(audience laughing)
35:41
I've got lots of counter-arguments against RSpec, too.
35:46
I just want to say you don't have
35:47
to include standard Rails,
35:51
this gem in your old code base
35:54
if it's going to cause a bunch of issues like that.
35:56
That's true.
35:57
(audience laughing)
36:02
I mean, he's not wrong.
36:10
All right, shall we vote?
36:14
In favor is green.
36:16
Oh, this is too close to call.
36:18
Is it? Oh, it might be.
36:21
I think this session's turning me colorblind.
36:23
Yeah. All right. Too close to call.
36:25
Too close to call. I think we got to disable.
36:27
We're going to have to disable.
36:31
Oh this is a fun one.
36:33
So this action order cop
36:37
mandates the order of your public methods
36:39
in your controllers to be first you define index
36:43
and then show and then new and then edit and then create
36:46
and then update and then destroy.
36:47
And if it's out of order, you're in violation.
36:50
Anyone have any comments?
36:53
I kind of like it.
36:55
I guess Aaron said it better,
36:56
but I was going to say this is ridiculously pedantic
36:59
and really annoying, like who cares?
37:01
Like is this what keeps you up at night?
37:03
So that's an argument.
37:05
It's an argument against turning this on
37:07
'cause it shouldn't matter what the order is, it doesn't.
37:10
Quadruple negative, it's a vote to disable.
37:12
(audience laughing)
37:15
One more counterargument?
37:16
Everyone knows that if you're being pedantic,
37:17
the proper order is alphabetical.
37:19
(audience laughing)
37:28
All right, let's vote.
37:33
Oh.
37:35
This is too close.
37:37
No. Okay. No, not too close to call. I'm going to.
37:39
I mean it's too close for my comfort.
37:41
That's right.
37:42
I don't like that we have this many greens up.
37:46
But it was like 60-40 red, right?
37:47
Yeah.
37:49
Alright, so the nays have it.
37:51
Here's another rule.
37:54
I got plenty.
37:55
Active record override,
37:57
this checks for overriding built-in methods
37:59
and active record, like save
38:01
instead of using callbacks to augment the behavior
38:05
of these built-in methods.
38:06
So if enabled, you can no longer define save again
38:10
inside of your custom model.
38:13
Comments, thoughts, murmurs?
38:20
Share that?
38:21
Do I want to share it?
38:23
I like using callback, so sure.
38:25
(audience laughing)
38:34
I could still have exception
38:35
on a case-by-case basis, right?
38:37
Yes.
38:42
One last comment.
38:44
Much as I dislike callbacks,
38:47
some of the biggest holes in my feet
38:49
were caused by places where we overrode
38:51
one of the standard methods like save or update attributes.
38:56
So the first comment elicited a lot of curious murmuring
39:01
and the last comment
39:02
elicited a lot of very aggressive head nodding.
39:05
(audience laughing)
39:07
We'll see how that translates to votes.
39:10
Let's vote on this one.
39:14
Easy. 90 10, the yeas have it, yeah.
39:16
Enabled.
39:18
All right, prepare to get confused again.
39:21
So Rails date, if you say date.today,
39:25
it doesn't take into account the time zone,
39:28
it's just the system time, free of time zone.
39:32
Which means that if your offset is like five hours
39:37
and it's the last five hours of the day basically
39:39
and you say date.today,
39:40
it'll actually give you the wrong day,
39:43
that you probably don't mean.
39:44
So if you enable this rule,
39:46
it basically steers you towards using like time.zone.today
39:50
instead of date.today.
39:52
And if you put it in strict mode,
39:54
it also doesn't let you use date.current or date.yesterday,
39:57
even though I'm pretty sure those do call through
39:58
to the time zone, maybe 'cause they look like today.
40:04
Andy.
40:06
I'm British and I don't see why this is a problem.
40:08
(audience laughing)
40:10
- All right, so Andy is a Greenwich supremacist,
40:16
who lives in the UTC and his CI always passes.
40:21
(audience lauging)
40:27
I have a code base
40:28
that has many devs in it and is riddled with these bugs,
40:33
these time zone related bugs
40:34
and where our test suite doesn't pass at the end
40:36
of the month for reasons.
40:38
(audience laughing) So I don't care if you put it in Standard or not,
40:43
I'm turning it on as soon as I get home.
40:45
(audience laughing)
40:46
All right.
40:48
All right, let's vote.
40:52
The yeas have it.
40:53
Yes, they do.
40:54
Sorry that this isn't that bright in Ruby, but.
40:59
What's our enforced style for date?
41:01
Enforced style?
41:03
We're going to keep it flexible
41:06
because Matthew Draper reacted really negatively
41:09
when I explained what the strict mode does
41:12
and he's smarter than a lot of us, at least me.
41:15
All right, so we actually just,
41:17
we're coming up on time, we only have a few minutes left,
41:19
which means we're going to go to the lightning round
41:22
where we're going to go by spicy order ascending
41:27
and we're going to try to get through
41:28
just some of these extra rules while we can.
41:31
So we're going to go as fast as possible,
41:33
not really explain what the hell is going on
41:35
and allow votes.
41:37
No more arguments, just votes.
41:40
And we'll see how many we get through.
41:42
we'll see what happens. Fun.
41:43
Okay, so where not, you know,
41:45
so you can't write not equals and not inside of your queries
41:49
instead of, coaches you to use where.not.
41:52
All right, let's vote.
41:52
Hands up. Turn it on.
41:55
Where missing.
41:56
So instead of doing that janky left joins thing
42:00
where you're like, Hey, is that association not there
42:01
or there, use the very cool dot missing method,
42:04
which I forgot existed,
42:06
which somebody just learned, I'm sure.
42:07
Yeah, it's pretty cool.
42:09
All right, the yeas have it.
42:11
Unused ignore columns.
42:14
So if you ignore a column and it doesn't exist,
42:18
it'll tell you to stop ignoring the non-existent column.
42:24
Cool.
42:30
Okay, Uniq before pluck.
42:32
So if you call pluck and then Uniq,
42:34
it will fetch from the database unnecessarily.
42:37
But if you call distinct or uniq and then pluck,
42:40
you're getting the idea that this is a very agreeable one.
42:43
Hands up, everyone's yes. Alright, cool.
42:46
Top level hash with indifferent access.
42:50
This one requires you,
42:51
if you want to instantiate a hash within different access,
42:53
meaning that the keys can either be strings or symbols,
42:57
you have to actually reference it
42:59
via the Active Support constant.
43:02
All right.
43:03
Everyone get that?
43:04
See, there are a few reds.
43:05
Oh.
43:06
We got a lot of abstainers.
43:08
All right, I think this too close?
43:09
That's too close.
43:11
What's that?
43:12
(audience member speaking indistinctly)
43:14
I don't know. Yes.
43:16
All right, so we're going to disable that one, I guess.
43:18
Time zone assignment.
43:19
So if you see code like this,
43:21
the bad time zone thing,
43:22
I think what that's doing is it's setting it
43:24
for the whole process.
43:27
And the good time zone is wrapped in a block.
43:32
So if enabled, it requires the block usage.
43:35
People are saying that's good.
43:38
Trust the wisdom of the crowds.
43:40
Strip Here doc.
43:41
So this will require you to use,
43:47
instead of calling strip here doc, the squiggly,
43:50
Ruby 2.3, end up squiggle gear docs.
43:55
All right, cool.
43:55
All right.
43:57
Scope arguments.
43:58
So this, instead of passing an argument
44:02
that is like relation made right away,
44:04
it's a block to that relation so that it's,
44:08
yes, run at the time of use
44:11
and everyone sees that this is a good idea.
44:13
All right, cool.
44:13
See, not very spicy. This is very bland.
44:17
Safe navigation with blank.
44:19
Can anyone tell me why the bad one is bad?
44:24
Right.
44:25
So it doesn't check anything
44:26
because nil responds true to blank.
44:29
And if the ampersand,
44:34
what's the right name for this operator?
44:37
The lonely operator.
44:38
The lonely operator, right?
44:40
So the lonely operator. Basically just bad, useless.
44:42
So everyone just vote now.
44:44
All right, cool.
44:45
All right.
44:46
Now, Safe Navigation.
44:47
Now this is try bang
44:50
does exactly what the lonely operator does now,
44:52
it just predates it.
44:53
So this says any try bangs should be converted
44:56
to lonely operators.
44:58
So let's vote on that first.
45:01
Okay, now there's a second mode here called convert try.
45:05
So try non bang, which will not,
45:11
wait, it will not raise an error if it's not defined?
45:13
The behavior is not identical is the point
45:16
between try and the existential operator.
45:21
You all get that?
45:22
Something about what response to.
45:24
Does anyone want to take a flyer?
45:27
Yeah, so try does what with respond to?
45:30
(audience member speaking indistinctly)
45:34
We don't know for sure how this works.
45:36
Right?
45:37
(audience laughing)
45:37
So turn it on, see what happens.
45:39
Yeah.
45:40
All right.
45:44
Let's not turn that on.
45:46
Let's keep it at default.
45:48
Okay, so we're right at time.
45:52
This was an experiment and it had a result.
45:58
(audience laughing)
46:00
It definitely had a result.
46:01
Like my most of my favorite experiments.
46:04
(audience applauding and cheering)
46:14
I appreciate all of your patience, all of your votes,
46:18
you can keep the paddle.
46:21
Feel free to bring it to your stand ups
46:23
or your PM meetings.
46:25
Yeah, wave it at your boss next time.
46:28
But thank you so much for hanging out.
46:30
You can run gem install standard-rails
46:32
and you'll get a sneak preview edition
46:34
that doesn't work quite right
46:36
and then we'll update it with these rules
46:38
and some more later on this week.
46:41
So thanks again.
46:42
Thank you.
46:43
(audience applauding)

Meagan Waller

Person An icon of a human figure Status
Double Agent
Hash An icon of a hash sign Code Name
Agent 0087
Location An icon of a map marker Location
Jacksonville, FL

Justin Searls

Person An icon of a human figure Status
Double Agent
Hash An icon of a hash sign Code Name
Agent 002
Location An icon of a map marker Location
Orlando, FL