[Ruby] [Ruby on Rails] Dissolving Fat Controller-First of all, logic to model-

1 minute read

Introduction

This is the first post this time. I learned Ruby on Rails at school and had a refactoring curriculum, but at that point I was desperate to complete it, and I did not refactor it so I moved the controller logic to Model and made the controller clean I will write the method.

What is Fat Controller?

It means the state of Controller where the number of lines in the controller itself is large and it is difficult to follow the flow of processing (simply speaking, the outlook is bad). At school, I wrote all the logic in the Controller without being aware of it at all, but I am still fighting with the personal controller Fat Controller because I want to get closer to the code at the working level!

Isolation procedure

First of all, let’s move on to the feeling that we will move all the controller logic that has expanded tremendously to the Model. Actions are enough as public methods to be written in Controller.

And I think that there is basically no problem in Model where the logic is transferred.

Example: When you want to pull only items that the user has

Before division ↓

ruby:users.controller.rb


def show
  @useritems = Item.includes(:images).where(user_id:(current_user.id)).order(id: "DESC") if user_signed_in?
end

Since the authentication function is implemented using devise, the id of the currently logged-in user can be obtained from “current_user.id”. In other words, I want to pull the information of the user’s item to my page (show action) of the currently logged-in user. However, this data is also used in the index action of “items.controller.rb”. So I’d like to define a method in Model and put together the description to get the user’s item.

First, Controller

ruby:users.controller.rb


def show
  @useritems = Item.user_items_get(current_user.id) if user_signed_in?
end

Since “current_user” cannot be used on the Model side, pass it as an argument.

Then Model

Item.rb


def self.user_items_get(user_bigint)
  Item.includes(:images).where(user_id:(user_bigint)).order(id: "DESC")
end

By doing this, even the index action of ItemController

ruby:items.cotroller.rb


def index
  @useritems = Item.user_items_get(current_user.id).limit(10) if user_signed_in?
end

You can use it like this.

If you write a method in Model and call it in Controller, beginners tend to feel that it is a big layer, but it is important for making Controller clean, so please use it. (I haven’t reduced the number of lines in this example… lol)