Why we should avoid default_scope in Rails

ActiveRecord in Rails provides a way called scope to keep the readability along with encapsulating the detail of the business logic in the model class. It enables us to add a more intuitive interface to the model so that we can quickly call the scoped method without caring about the complicated underlying implementation. This also contributes to achieving the well-known good practice in the MVC model, “Fat Model, Skinny Controller”. It shows us the clear guidance saying, “We should not write non-response related logic in the controller”. If you are writing a complicated logic that is not directly related to the HTTP response construction response, that should go to the model, not controller. scope methods are helpful to materialize this goal.

What is default_scope?

As part of the scope feature, ActiveModel has a default_scope which defines the scope method applied to all queries on the model. Let’s say we have a User model as follows.

class User < ActiveRecord::Base
end

User.all returns all users as it states. But what if you want to get the users excluding all hidden users. The following code will return the results as you expected.

User.where(hidden: false)

But default_scope will provide a more convincing manner.

class User < ActiveRecord::Base
  default_scope { where(hidden: false) }
end

This default_scope is always applied to the model query. In other words, you do not need to specify the query explicitly anymore.

User.all # It will return the visible users, excluding hidden ones.

That is good. You do not need to specify the same where conditions many times. default_scope automatically creates the basis of all queries.

Practically, default_scope is often not recommended in Rails.

Implicit Behavior Change

Based on my experience, the biggest problem of the default_scope is applied implicitly. If the writer of the default_scope is different from the model user, the behavior must look weird. Model users will see a query they do not write unexpectedly. Implicit behavior change is generally anti-pattern. (In Scala, even the compiler shows the warning for the implicit type conversion.).

In my case, I have developed one API using the model class, which is derived from the original web application. Since the data source is shared with them, it is useful to share the model class too. But it brings unexpected pitfall caused by default_scope. At some time, another developer introduced the following default_scope.

class OriginalClass < ActiveRecord::Base
  default_scope { select(all_columns) }
end

An application I have developed is using the class. What I want here are only c1, c2, and c3. Returning all columns can cause the problem.

OrignalClass.where("c1 = xxx").select("c1, c2, c3")

As you imagine, introducing the default_scope here makes it happen. Without any notice, all columns are returned because I do not know the change around the default behavior of the OriginalClass.

Implicit behavior change is always requiring intensive care. All developers touching the codebase and related repository need to be careful of the transformation of the behavior. But we must not expect all members to do so. It’s unrealistic.

Use scope, not default_scope

Here is a simple answer. Use scope, not default_scope. What we want to do was completely achieved by scope. There was no special reason to use default_scope.

class OriginalClass < ActiveRecord::Base
  scope, get_all_columns -> { select(all_columns) }
end

Using scope does not break any user codebase implicitly. If a user wants to make use of this new scope, call it explicitly. Of course, default_scope can reduce the amount of code you need to write in terms of the number of characters. But the damage and maintenance cost will surpass the benefit obtained by the default_scope. Simply obeying the following guidance will lead you to keep the Rails code clean and more maintainable.

Use scope, not default_scope

Thanks for reading!

References

Google Keep for TODO List

When you get a chance to learn a new programming language or framework, you might encounter the exercise to develop a TODO app. The reason behind this kind of exercise is that the TODO app generally covers all functionality most web/mobile app needs, such as user identity management, data persistence, and presentation rendering. Still, the TODO app lets us feel familiar. Everyone can understand the specification of the TODO app at a glance without much prior knowledge. TODO app is one of the applications we frequently use day by day.

But finding the best TODO app was not an easy task for me in the real world. I tried several TODO apps for my work/personal life.

They did not work for me so much due to the following reasons.

  • They are too complicated. In other words, it has too many functionalities. I love the simple one.
  • Some sort of management for tasks is still necessary. Putting all tasks in flat space is not useful for searching.

Although Todoist, Wunderlist, Evernote provide me many features, most of them are not necessary to me. The note is a simple note application so that we cannot organize the memos in order.

Is there some TODO app satisfying these requirements?

Google Keep

TODO

I found one of my colleagues using Google Keep as a TODO app. Google keeps an application providing Post-It like user interface. We can maintain any resource (e.g., picture, text, link) there quickly. It’s more like a simple memo application. But the notable thing of Google Keep is also providing the fine-grained search feature (as most of Google product does). We can search by text, labels we attached, and colors specifying the type of the note. Of course, Google provides mobile apps for Google Keep.

I like Google Keep because it achieves the right balance between high functionality and simpleness. It’s not designed purely as a TODO app. Thanks to that fact, Google Keep is probably the handiest TODO app.

You would not get lost how to use Google Keep. It’s easy to understand the full functionality. I’ll pursue the way to use Google Keep as a better TODO app furthermore.

Thanks!

Image by Markus Winkler from Pixabay

Light way to remove whitespace in PostgreSQL

We might have the experience to remove the white space in the string recorded in PostgreSQL. There is a function TRIM, but it only removes the white space on the left/right side of the string. How can we do that when we want to omit the whitespace in the middle of the given string?

REGEXP_REPLACE is available to replace any string with the regular expression pattern.

SELECT regexp_replace(some_string, '[\s+]', '', 'g') FROM table;

By using the flag g, it replaces all characters appearing in the given string. That would be a flexible and powerful way to replace any characters with PostgreSQL.

Photo by Markus Spiske on Unsplash

Visualize COVID-19 situation in Japan

Visualization often provides us a vivid image to grasp the situation at a glance. It is one of the recommended ways as a starting point of more in-depth understanding and investigation in general.

COVID-19 keeps spreading all around the world. The number of infectious cases is growing, especially in Europe. That challenge will keep going on for a while. The prolonged war reminds us of the criticalness to get the correct information consistently, and visualization will play a significant role in helping various kinds of effort. For instance, many visualization works are happening to help people understand the situation and deal with this challenge as follows.

As a part of this type of effort, I have created another tool to provide statistical information related to the COVID-19 situation in Japan. It includes the aggregated statistics relating to the medical system in Japan supporting COVID-19 remediation.

What is Choropleth

A choropleth map is a type of map in which areas are shaded in proportion to statistical measurement. The map is useful to see aggregated information by the area segmented on the map quickly.

The tool used a choropleth map to illustrate the statistical measurement at a glance. Here is the illustration provided by the tool.

preview

The data was obtained from the following sites.

Regarding the statistics from the census, it uses the data in 2013, which seems to have higher coverage in terms of medical and health care attributes.

Supported Data

Currently, the following data is supported.

  • Total population
  • Total confirmed cases of COVID-19
  • The ratio of confirmed cases to the population
  • The ratio of hospitals to the confirmed cases
  • The number of hospitals
  • The number of beds per 100,000 people
  • The number of doctors per 100,000 people

I will continue to extend the data set to show the COVID-19 situation from various kinds of perspective.

Acknowledgement

The original tool created by ncovis designed to visualize the situation in China profoundly inspired my visualization. The design and appearance of the ncovis/choropleth were so impressive to me that I decided to make use of it. I appreciate the ncovis’ work.

Open Dataset for COVID-19

The epicenter of the outbreak of COVID-19 moves to Europe in these weeks. The situation is still highly unpredictable. We need to manage to keep away from the threat of the COVID-19. Washing hands properly and staying away from the crowded area is our duty to stop the spread of COVID-19.

Fortunately, many scientific efforts are happening to deal with COVID-19. Various kinds of data set are publicly available. We can create an application based on that to support people or get new insight into the mechanism of COVID-19. In this post, I made a list of useful data sources or projects related to the COVID-19 issue. These data was useful to write the previous blog post for sure.

Cases Data

tokyo

Open Source Projects

Open-source software or applications for public usage related to the COVID-19 issues.

wuhan

Scholarly Articles

In response to the COVID-19 pandemic, Allen Institute for AI published the research achievement as free scholarly articles, which is named CORD-19. The dataset is expected to be used to find a new insight by mobilizing the natural language processing technology. The data is structured, and metadata contained a machine-readable format so that we can make use of the technology to explore these data.

Competition

A new competition is launched using the CORD-19 dataset. Correctly, it’s not a competition in the usual sense in Kaggle. There is no award, score, and ranking there. It is a real-world challenge to tackle the COVID-19 outbreak. Our responsibility is to find useful insight and contribute it to the community so that we can fight the problem and defeat it hopefully soon.

Challenge

Last but not least…

It is crucial not to spread the wrong information or fake news. We should always check the primary source of information when you have any doubts. Please be aware of the site of WHO and other official announcements from your local government.

I sincerely hope the situation will recover soon.

Image by Markus Spiske from Pixabay