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!