RailsConf 2023

Let's Standardize Rails, Once and For All!

Let's Standardize Rails, Once and For All!

by Justin Searls and Meagan Waller

The video titled "Let's Standardize Rails, Once and For All!" features Justin Searls and Meagan Waller discussing the evolution of the Standard gem, a Ruby linting and formatting tool that helps maintain consistency across Ruby projects. The session, held at RailsConf 2023, is centered around creating a new gem called standard-rails, which aims to establish a set of RuboCop rules tailored for Rails applications. Here are the key points discussed throughout the event:

  • Introduction of Standard: Justin explains how he created the Standard gem in 2018 to eliminate arguments over RuboCop configurations that many development teams were experiencing. The goal was to lock down configurations, allowing developers to focus on building rather than debating stylistic preferences.

  • Community Involvement: Unlike previous iterations, Justin emphasizes that the new standard-rails will rely on community input through a straw poll model at RailsConf. This democratic approach intends to gather collective insights on RuboCop rules and enhance consistency across various Rails applications.

  • Voting Process: Attendees are engaged in a hands-on voting process using paddles to express their consensus on different proposed rules. The session involves lively debates about the advantages and drawbacks of specific linting rules, highlighting the importance of moderation in tool configurations to avoid friction when writing code.

  • Examples of Specific Rules: The discussion includes various proposed rules such as:

    • Active Support Aliases: Debate on whether to prevent the use of Rails' Active Support methods in favor of core Ruby methods.
    • Timestamps in Migrations: Consideration of requiring timestamp fields in database tables.
    • Environment Variable Access: Discussion on whether to enforce the usage of Rails’ application secrets rather than raw environment variables.
  • Conclusions and Takeaways:

    • The session concludes with a lighter mood, emphasizing collaboration and community input in shaping the future of Rails linting rules. The presenters highlight that participants are encouraged to continue engaging in feedback and discussions regarding standard-rails, promising an initial release incorporating community-selected rules soon after the conference. Justin hits on the importance of reducing friction among developers while maintaining coding standards that adapt to various Rails projects.
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!