It's a general architecture that we are aware of when developing Rails.
A memorandum note that you are conscious of not becoming a fat controller or fat model. Since it is a random sentence, I will correct it as appropriate.
Ultimately, I think the responsibility of having the controller follow is as follows.
** "Create an instance, execute a method on it, and return a response" **
only this.
This is the worst thing to say.
ruby:example.contoroller.rb
There is no such action
def index
@most_funded_projects = []
most_funded_projects = Project.most_funded.includes(:main_image)
most_funded_projects.each do |most_funded_project|
break if @most_funded_projects.count >= 3
if @site_project_descriptions[most_funded_project.id].present?
@most_funded_projects << most_funded_project
end
end
if @most_funded_projects.count < 4
current_site.published_projects.order(updated_at: :desc).each do |project|
break if @most_funded_projects.count >= 3
@most_funded_projects << project
end
end
end
Gorigori's business logic is written on the controller. I used to write such a controller, and I was careful. If you make a controller with scafold, you can make a controller with the following simple shape, but basically it is ideal to make it according to this feeling.
example.rb
def index
@friends = Friend.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @friends }
end
end
In short, the following is the basic form
@hoge = Hoge.new
@hoge.hoge
Returns a response
In the controller, it was important to have an image of creating an instance associated with the model and executing a method on it. So once you think about putting all your business logic into the model. However, since there is another problem in putting everything together, the image of putting things in the model is mainly ** things related to persistence and business logic ** that is completed by operating a single model. is.
The patterns to be implemented in the model are generally as follows.
--Get record of table associated with model (ActiveRecord operation) --Data acquisition including related tables based on the table associated with the model --Update the data of the table associated with the model --Other business logic linked to a single model
I think that simple processing such as simple update of a single table is mainly applicable, and other than that, business logic that is completed with a single model.
Processes such as multiple model operations and file operations are cut out as a service layer as a unit of atomic business logic.
Basically, create a normal class that is not tied to ActiveRecord (it is not tied to the table one-to-one) in the following form. It's like creating a class and separating complex logic across multiple models from an existing model. It's simple to use, just create an instance of the class and execute the methods you've created for it.
exmple.rb
class ExampleService
def initialize
....
end
def example
....
end
end
Even with the method introduced, if the model or service class becomes fat, cut the namespace under the models directory, create a simple class that is not one-to-one with the table, and the model or service that became fat there. There is also a technique to prevent the model and service class from becoming fat by transferring the methods that can be used for general purposes in the class. You can also use consern to combine redundant things into one. For example, it is an image that creates models / {table name} / {use case} .rb and cuts out the process. For better visibility, define instance variables in Controller.
--The Controller and Service layers basically perform only procedure processing *. * Procedure processing is to call a function or perform processing related to CRUD. --The Controller and Service layers only use the returned data and are not involved in logic or data processing. --The Service layer makes good use of the methods that grow in multiple models when the processing in the Controller spans multiple Models, creates methods in the service class, and mainly uses them for instances. For example, in processing that spans multiple models, the instance method that originally exists in each model that is supposed to straddle is used in the service class, the method is created in the service class, and the instance of the service class is created in the controller. Then, it takes the form of executing a method using it as a receiver. --I don't want the service class to be fat as much as possible, so if the business logic is bulky, I would like to cut the consern and namespace and create another class under the models directory. Create models / {table name} / {use case} .rb and cut out the process. In order to improve the visibility, instance variables should be defined in Controller. --Be sure to process logic and data with Model