RailsConf 2014

Tricks That Rails Didn't Tell You About

Tricks That Rails Didn't Tell You About

by Carlos Antionio da Silva

In the RailsConf 2014 talk titled "Tricks That Rails Didn't Tell You About," Carlos Antonio da Silva shares lesser-known features and best practices in Ruby on Rails that can simplify complex code. He begins by highlighting the complexity that often arises in Rails projects, emphasizing that many developers may overlook existing tools and features provided by Rails.

Key Points Discussed:

  • Complexity in Rails Applications: Carlos reviews common challenges such as duplicated code, large controllers, and complex methods that developers face when working with Rails.
  • Active Record Enhancements: He introduces several Active Record features, such as the change method for migrations that can simplify migrations without needing to specify column types, and the use of merge to reduce duplication in query conditions.
  • Eager Loading Strategies: Carlos discusses the importance of optimizing database queries through Active Record methods like includes, preload, and their performance implications.
  • Action View and Helpers: He covers the use of helpers for rendering collections and controlling output, including strategies for rendering empty collections effectively.
  • Internationalization (i18n): Insights on best practices for translating strings in views without introducing security vulnerabilities are provided.
  • Benchmarking: Carlos presents a built-in benchmarking method in Active Record that allows developers to log the performance of database queries, providing important metrics for optimization.
  • Using Active Model: He explains how to leverage Active Model for validations and form handling to make non-persistent models behave like Active Record, streamlining the development process.
  • Advanced Routing Techniques: The session touches on routing parameters and handling redirects more efficiently with interpolation.
  • Useful Development Practices: Carlos encourages leveraging Rails console features, such as the sandbox mode for testing without permanent changes, and the use of annotations for marking code improvements or optimizations needed.

Conclusions and Takeaways:

  • Developers often miss using Rails' built-in features which can lead to complexity and inefficiency.
  • Understanding and adopting these lesser-known tricks and features can significantly enhance productivity and maintainability of Rails applications.
  • Continuous learning and sharing of knowledge within the Rails community can uncover new ways to utilize Rails effectively.

In conclusion, Carlos emphasizes that before drafting custom implementations, developers should consider if Rails offers an existing feature that could simplify their work. He encourages a culture of sharing findings and improvements within the community to enhance overall development practices.

00:00:23.680 So we are here to talk a little bit about some tricks that we didn't tell you about.
00:00:29.760 My name is Carlos Antonio da Silva, which is my Twitter handle, and I've been working with Rails for around six years now, maybe a little more due to some freelancing work. Before actually starting to work full-time, maybe that's why people keep telling jokes about my gray hair. During these years, I've participated in several different projects, with a variety of cultures, from small projects to big ones, and small teams to large ones.
00:00:42.239 I have seen a lot of different code throughout these years working with Rails. I've encountered a range of complexities; some code is more intricate than others. For instance, the guys yesterday mentioned seeing a method with around 90 lines of code, along with controllers that exceed a thousand lines. It's truly complex and often difficult to work with.
00:01:08.320 I've also encountered a significant amount of duplicated code in these projects. Does anyone here know of any piece of code in the application you are working on that is duplicated but you're a bit hesitant to deal with because you're afraid of breaking it?
00:01:15.360 This is a common problem. What makes me sad is when I see applications utilizing Rails features implemented poorly in the application code. Has anyone here ever seen a feature in your application that could be replaced with a Rails feature or an existing feature? Yes? Well, this type of situation is disheartening because there are numerous Rails features available for us that we continue trying to implement ourselves. We frequently normalize this duplication over time, becoming desensitized to the code. We might identify that there are some Rails features available, but we are scared to touch that code; we're just accustomed to it.
00:02:02.640 This, ultimately, leads to a significant problem where we grow accustomed to the code and are apprehensive to modify it. So let's see if today we can improve this situation a bit with some Rails features that I will show you. Hopefully, these features will help you refactor existing applications or perhaps enhance your developer experience moving forward.
00:02:21.200 I work at Plataformatec, a consultancy based in São Paulo, Brazil, with about 30 people. We're heavily focused on Ruby and Rails development. Since we are talking about Brazil, I should mention the World Cup. Is anyone here planning to attend the World Cup? Cool! You're going to have a great time.
00:02:38.839 Plataformatec deeply values open source. We strive to contribute actively to various open-source projects, including Simple Form and Devise. Who's using Devise here? Awesome! Well, Devise was released around five years ago, and we had conferences announcing its launch back in Brazil in 2009.
00:02:53.440 In addition to Devise, we also have Simple Form. Has anyone used it before? Great! We're also working with Elixir, which is an interesting language. Who here has tried it? Recently, we discussed that in our team, and in addition, we leverage a lot of pull requests and code reviews; we do this continuously.
00:03:13.679 What’s nice about this process is not only do we conduct reviews on our own projects, but we also review code across different projects. This cross-project experience allows us to consistently learn new things.
00:03:29.120 We have about 30 people developing software, and each person brings varied knowledge. When we share code across projects, we often come across new methods or techniques that others have implemented.
00:03:40.400 Discussion often arises regarding the choice of one method over another. Our team emphasizes explaining and discussing the reasons we choose one solution over another. We also give hints about when to use certain methods to optimize our code.
00:03:53.440 This dynamic inspired me to consider why I shouldn’t stop after just looking at my approved pull requests. It sparked the idea for this presentation today. We will explore some neat Rails features that are often underutilized or not very well documented.
00:04:11.280 Let's start with Active Record. It's quite powerful!
00:04:20.159 To begin with migrations, I've noticed some projects where developers struggle to change a specific attribute. In this example, I'm changing the `name` attribute of the `authors` table. The issue with using `change_column` is that you must specify the type of the column you are changing.
00:04:35.680 If you only want to change a flag on that column, you can instead use `update_column`, which allows you to change the flag without specifying the type of the column explicitly. It's a more effective way to accomplish this announcement.
00:04:58.560 One last side effect of this method is that you can use the `change` method in migrations to make it reversible, allowing you to run both `up` and `down` methods seamlessly.
00:05:06.640 We also have a way to change the default value of a column, which is useful when you want to specify new defaults without needing explicit change methods for each.
00:05:14.640 For example, there is the `change_column_default` helper that allows you to set a new default for a column.
00:05:28.160 Next, let's discuss conditions. Consider an author model that associates with multiple articles.
00:05:38.240 Articles can be in different statuses, such as draft or published. Here, I want to demonstrate how to retrieve authors who have articles in the draft state.
00:05:49.120 To achieve this, I perform a join on the articles association and set a condition to filter for articles with a status of 'draft'. This method works well.
00:06:03.360 The downside is that the author model becomes overly dependent on the definition of what constitutes a draft condition for an article.
00:06:13.680 To refactor this, we can use the `merge` method to transfer conditions from another model's scope. Instead of directly referencing `articles.status`, we merge conditions from the article's draft scope.
00:06:23.680 This helps eliminate duplicate logic and centralizes what defines a draft article.
00:06:30.760 So, if the definition of what constitutes a draft changes, it only needs to be modified in one place.
00:06:36.760 Additionally, using a `group` method is helpful when summarizing data counts across different statuses of articles.
00:06:45.440 For instance, you can group articles by their `status` and count each category, which allows you to effectively summarize your data.
00:07:01.919 This provides a clean way to overview the distribution of your article statuses.
00:07:10.200 Moreover, if you need to retrieve specific records based on defined conditions, it's essential to use mechanisms that minimize the occurrence of unnecessary queries.
00:07:19.919 For instance, if you want to search for articles that do not meet a specific criterion, employing the `not` query will help provide clarity by allowing you to facilitate a clean search.
00:07:34.000 This way, it automatically references the table name correctly, which is more straightforward and enhances the code's readability.
00:07:44.480 Moving on, let's discuss some eager loading strategies.
00:07:54.560 As you know, Active Record has an includes helper that can prevent N+1 query problems. Normally, it runs two separate queries: one for the articles and another for the authors.
00:08:06.720 However, when you add conditions to the search that require data from the authors, Rails internal optimizations allow it to merge them into a single query, minimizing database hits.
00:08:18.560 You can also explicitly tell Rails which loading strategy to use by utilizing methods such as `includes`, `joins`, or `preload`.
00:08:28.080 Each of these methods is suitable under specific circumstances, and knowing when to use them is crucial for performance optimization.
00:08:38.960 In addition to eager loading, you can utilize scopes and chained queries effectively.
00:08:48.240 You can utilize hashes to create concise and readable ordering conditions in your queries.
00:09:02.640 For instance, if you require a list of unique article tags or author names from your database, Rails makes it easy to obtain this information by actively selecting attributes.
00:09:14.760 Additionally, if you want to gather unique results, utilizing the `distinct` method can help avoid redundancy in your result set.
00:09:24.640 Next up, let’s talk about rendering and helper methods.
00:09:32.640 The `link_to` method combined with Rails paths allows for the dynamic generation of routes while maintaining clean and understandable code syntax.
00:09:45.440 This is particularly useful when you wish to link to resources while ensuring your URL outputs are logically defined and concise.
00:09:58.960 Using the concise routing methods allows for enhanced maintainability and reads easily, making it purposeful when writing new features.
00:10:07.919 Next, let’s dive into views and rendering collections.
00:10:15.679 Rendering collections with a check for emptiness can save time and energy and ensure that you are not facing issues when no data exists.
00:10:25.440 For instance, when rendering a list of articles, if there are no articles, it returns nothing gracefully.
00:10:34.880 Moreover, local variables can facilitate clearer logic when rendering partial views, giving you the flexibility to control the output based on context.
00:10:45.760 Using `local_assigns`, you can determine how to display data based on its context, allowing for custom presentations.
00:10:54.640 Another helpful feature is the `truncate` method, which can accept a block that executes when the text is truncated, allowing you to handle scenarios where not all content is displayed.
00:11:10.240 For internationalization, you can integrate I18n effectively without introducing cross-site scripting vulnerabilities by using Rails' built-in methods.
00:11:23.520 Instead of manually escaping each piece of translated content, employ methods that automatically mark it safe.
00:11:34.080 The same goes for Action View; the `content_tag` method lets you seamlessly generate HTML tags with specified collections, improving the readability of your view templates.
00:11:43.360 Perfectly organizing routes can enhance the flow of your controller actions, especially when dealing with nested resource calls.
00:11:56.000 Additionally, automatic rendering of application layouts for error handling improves user experience while maintaining consistency.
00:12:05.440 Moreover, on the console, methods like `add_variable` give you access to helper methods as if you were performing unit tests.
00:12:14.080 The console is a powerful tool for debugging and testing specific characteristics of your code.
00:12:23.920 You can establish shortcuts within your console for recurring tasks, which increases productivity.
00:12:34.160 Lastly, using the sandbox mode allows you to experiment without risking damage to your database.
00:12:43.040 Updates in Rails have become more streamlined, enabling users to employ tools that assist in managing version control and migration processes.
00:12:54.720 It’s advisable to utilize automated tasks to ensure you’re aware of the appendix that comes with version updates.
00:13:05.440 Finally, remember that Rails continuously evolves, and its new features can significantly enhance our coding experience.
00:13:17.520 Every time you start a new project, take a moment to check for new functionalities that could streamline your development.
00:13:27.840 The community thrives on shared knowledge, so never hesitate to share your findings with others, whether it be through social media, blogs, or discussions.
00:13:40.000 Each hidden gem you discover in Rails can make a great difference in your productivity and how you approach development.
00:13:53.760 Thank you!