RailsConf 2017

Tricks and treats for new developers

Tricks and treats for new developers

by David Padilla

In his talk "Tricks and Treats for New Developers" at RailsConf 2017, David Padilla shares essential tips and tricks for developing applications using Ruby on Rails. Targeted at new developers, the presentation emphasizes the nuances beyond simple tutorial projects, delivering practical insights based on Padilla's own experiences.

Key Points Discussed:
- Configuration Files: Developers should create example configuration files (like the database file) and ignore the originals for easy reference, enhancing collaboration and easing new developer onboarding.
- Schema Files: It is crucial to maintain the schema file for restoring the application's database state, and developers should address conflicts rather than ignoring them.
- Data in Migrations: Caution is advised when changing data in database migrations due to potential downtime and future coherence issues. Instead, data changes should be handled separately using data migrations or SQL.
- Background Jobs: When using background jobs, passing object IDs instead of full objects avoids performance issues and errors. Always opt for delivering emails later to ensure stability during transactions.
- RESTful Design: Developers should adhere to REST principles by limiting controller actions to standard ones (index, show, create, update, delete) and creating separate controllers for specific actions like filtering or applying discounts.
- Essential Gems: Padilla recommends using tools such as Rubocop for code analysis to maintain clean and effective coding practices, emphasizing how these tools can help enforce good coding standards even within larger projects.
- Memory Management: Key recommendations include using gems like Bullet to detect N+1 queries and memory leaks, streamlining the development process and improving application performance.

Through relatable anecdotes and foundational knowledge, Padilla's talk serves as a guide for beginners to enhance their skills and navigate the complexities of Rails development effectively. By focusing on configuration, structural integrity, and best practices, he illustrates how systematic approaches can lead to more manageable and efficient coding endeavors.

00:00:12.230 Welcome! My name is David, and you can find me on the internet at Dabit on Twitter and GitHub. I work for a company called Michelada.
00:00:17.490 Like the drink! If you've never had one, Michelada is a great drink that Mexicans enjoy all the time. It's made with ice, clam juice, magical Mexican sauce, chili powder, salt, lime, and of course, beer! It's delicious, and you should try one if you haven't.
00:00:36.329 Anyway, the name of my talk is 'Tips and Tricks for New Developers.' I will give you some context on why I decided to give this talk, which goes back to 2009 in a galaxy far, far away: Las Vegas.
00:00:50.370 At my first RailsConf, it was great! I was just getting into Rails and had my first job, where I was being paid to write my first Rails app. I was building a huge e-commerce platform but knew nothing about the real stuff—what happens once you are past the tutorial phase of Rails?
00:01:07.799 I remembered that there were several talks at this RailsConf that changed my perspective and helped me a lot. Topics included solving the riddle of search using Sphinx with Rails, which made me realize that it might not be a good idea to filter my products with SQL or perform searches using traditional methods.
00:01:20.729 I learned there was a better way to search, and we ended up using Solr instead of Sphinx. I also learned about Webrat, which was used to test applications before we had all the fancy new tools available. These insights were crucial for my development journey.
00:01:34.500 One of the most important lessons I learned was about Git. Before that, I was using SVN and Visual SourceSafe, and discovering Git was a game changer for me. I clearly remember a talk titled 'Git in 60 Seconds' that impressed me immensely.
00:01:41.880 The speaker read through the essentials of Git in less than a minute, which was amazing, and then he proceeded with a more detailed discussion, which I found incredibly valuable.
00:01:50.370 Another important insight I gained at RailsConf was about Mongrel, the web server we had to set up for our applications back then. I learned how to configure it with different ports, run multiple Mongrel processes, and use Nginx or Apache as a reverse proxy.
00:02:07.260 Scaling up was straightforward: you just added more servers and a reverse proxy to manage them, which was a particular practice in 2004. Looking back, I believe we still need talks like these for beginner developers at RailsConf. While there are talks on microservices and optimizing performance for high requests per second, it's essential to have sessions for beginners to help them learn foundational knowledge.
00:02:36.220 This talk is tailored toward beginners. Some of the things I’ll share may be familiar to you, but I hope they resonate based on my experience. These tips are what I typically apply when starting a new Rails application, and I genuinely hope they help you as well.
00:02:55.090 To kick things off, let’s discuss configuration files. When you start a new project, you use the 'rails new' command, which creates several files. It's a good practice to copy your database configuration file to an example file and ignore the original one.
00:03:11.569 This way, you always have a template to rely on. It’s frustrating to start your Rails server only to find you don’t have a database YAML file, and then you have to Google it or refer back to the tutorial. Creating this example file will save you precious time in the future.
00:03:36.570 Additionally, for any configuration file you think is necessary for the project to run, please create sample files. You can separate these files for better organization. For example, you can have a specific configuration file for payment settings, making your project clearer and easier to maintain.
00:03:54.630 Remember that when a string or an integer is compared to something else in the code, it's often better to use a constant instead. By defining configuration details in your config files, you'll save time when changes arise.
00:04:05.640 If your boss asks for changes to a time setting, such as adding a timeout duration, you’ll know exactly where to adjust this value instead of digging through the codebase trying to find it.
00:04:13.950 Let’s move on to database files. Over my eight years as a Rails developer, I’ve seen a common issue: the 'schema.rb' file getting ignored. Please do not ignore this file! I've joined teams where the schema was missing due to conflicts, which is a big mistake.
00:04:30.020 It’s critical to restore your database state using either 'db:setup' or 'db:reset', especially if you are new to the project. If you don't have the schema, you will struggle to set things up properly.
00:04:49.420 If there are conflicts in the schema, discuss them with your fellow developers rather than ignoring them. This is very important for maintaining the integrity of your project.
00:05:06.920 Here’s a tricky piece of advice: be cautious when changing data in your database migrations. It's common to add a new column to an existing table and then populate it based on current data, which often leads to problems.
00:05:28.370 For example, if you're splitting a column into two, adding new columns, and removing the old one, realize that this isn't future-proof. If the model changes later, your migration could fail, and migrations shouldn’t last forever—this is where the schema.rb file comes into play.
00:05:46.720 Another issue is that extensive migrations can lead to longer deployment times. If you run a migration in production that must iterate through millions of records, this can leave your application in a weird state and potentially bring it down.
00:05:55.540 To avoid downtime due to complicated migrations, consider using raw SQL for data changes. This approach is faster and safer because it avoids complications with Rails object persistence.
00:06:12.750 Using a gem like 'rails-data-migrations' can also be beneficial. This gem gives you a separate set of rake tasks for your data migrations, keeping your database structure migrations clean and separate from data changes.
00:06:31.780 When you create a data migration, it can be stored separately, making it easier to manage and reducing clutter in your main migration file. This practice also helps with tracking how changes are made over time.
00:06:49.120 Now let's talk about background jobs. Using background processing, such as Sidekiq or Delayed Job, is essential in modern applications. However, it’s crucial not to pass objects directly to background jobs.
00:07:01.350 Instead, pass IDs and then find your objects again within the job. Passing whole objects can lead to large serialized data that can cause issues, especially if there are special characters involved.
00:07:19.550 Always opt for passing integers—this way, you reduce the risks and make the process smoother. Additionally, when handling emails in your application, always deliver them later using background jobs.
00:07:38.050 Don’t wait until your first SMTP authentication error triggers a failure in your checkout process because you expected to send an email right after payment completion. Start your application with a plan to deliver emails asynchronously.
00:07:55.050 When using mailers, try to avoid passing objects; instead, pass their attributes or IDs. This approach allows you to maintain flexibility by simply adding a 'deliver later' method as you integrate background job processing.
00:08:15.700 Now let’s discuss RESTfulness, which is one of the core principles of Rails. You should maintain RESTful actions in your controllers that correspond to database CRUD actions—index, show, new, create, update, or delete. Avoid adding non-standard actions.
00:08:36.510 For instance, having a 'deactivate' action in your products controller is not RESTful. Instead, create a separate controller for handling the state of the product. This approach aligns better with REST principles.
00:08:51.580 If you're managing a shopping cart, instead of having a specific action for applying discounts, create a separate controller for discounts and handle the discount creation within that context. This keeps your code organized.
00:09:11.760 Every request should correspond to a resource that's changing, ensuring your application remains coherent with REST principles. If you have actions that do not fit into this model, they need to be re-evaluated.
00:09:26.380 Now let's talk about some Ruby gems I believe every project should include. They have proven to be incredibly useful. One of them is RuboCop, which analyzes your code and gives you feedback on best practices and style violations.
00:09:46.520 You may be hesitant to introduce it into a legacy project due to existing issues, but you can run it with the 'auto-gen-config' option to create a .rubocop.yml file that temporarily ignores all current offenses.
00:10:05.960 This approach gives you a fresh start while committing to fixing these issues over time, ultimately leading to a cleaned-up codebase moving forward.
00:10:20.440 RuboCop can help enforce code style rules, such as character limits per line. I usually set mine to a specific length, as it improves readability. Well-structured code is essential, especially if you’re collaborating with other developers.
00:10:35.600 Also, RuboCop's 'Metrics/MethodLength' rule encourages you to keep methods under ten lines. This makes your code cleaner and easier to read, as long as you don’t exceed this limitation significantly.
00:10:53.740 Incorporate hooks to execute RuboCop before you push code to your repository. By placing a script in '.git/hooks/pre-push', you can automatically run RuboCop to check for issues before committing changes.
00:11:14.880 This helps maintain code quality and prevents problematic code from being pushed upstream. In our team, we have a CI server running RuboCop, and I've seen countless commits that were only meant to fix style issues.
00:11:34.220 Next, let’s touch on the gem 'annotate', which I find incredibly useful yet often overlooked. After running your migrations, this gem annotates your models with information about the corresponding database columns.
00:11:49.070 If you make changes to your migrations, simply rerun the annotate command to update this information at the top of your model classes. It serves as a useful quick reference while working on your models.
00:12:06.390 This gem also has a feature to annotate your routes, saving you time searching for route definitions in your application. If you are an old-school developer like me who uses VI, you'll appreciate the contextual autocomplete available.
00:12:18.880 Moreover, I highly recommend using the 'bullet' gem to help detect the N+1 problem during development. This situation arises when you have queries that load objects inefficiently, leading to performance issues.
00:12:37.300 The bullet gem offers real-time feedback in your logs, suggesting optimizations to include related objects in your queries, which improves performance and enhances your application's efficiency.
00:12:55.310 Another great tool is a gem that detects memory leaks. Memory leaks can be challenging to identify, especially in Rails applications. If your application starts using excessive memory, setting up monitoring tools will help facilitate early detection.
00:13:08.620 This gem keeps track of object instantiation in your application and can give you insights into what's consuming memory during requests. Enable it while developing to pinpoint issues more effectively.
00:13:25.630 That brings me to the conclusion of my talk. I had to remove some pieces of information, but these tips are some of the most important lessons I've learned throughout my Rails development career.
00:13:30.640 Thank you for your time!