Reputation: 259
I have this logic below. Two controllers have same logic inside of their actions. common_logic1 common_logic2 common_logic3
, and I want to separate the common logic but dont know HOW TO DO that.
class ServicesController < ApplicationController
...
def download
some_logic_for_services
common_logic1
common_logic2
common_logic3
end
...
end
class PackagesController < ApplicationController
...
def download
some_logic_for_packages
common_logic1
common_logic2
common_logic3
end
...
end
The first way is making method to ApplicationController and inherit it. But I think this way goes to the end of fat applicationController.
class ApplicationController < ActionController::Base
...
def common_logic
common_logic1
common_logic2
common_logic3
end
...
end
class ServicesController < ApplicationController
...
def download
some_logic_for_services
common_logic
end
...
end
class PackagesController < ApplicationController
...
def download
some_logic_for_packages
common_logic
end
...
end
The second way is to separate the logic to helper module and include it. But I think helper is for separating logic from view.
module CommonHelper
...
def common_logic
common_logic1
common_logic2
common_logic3
end
...
end
class ServicesController < ApplicationController
include CommonHelper
...
def download
some_logic_for_services
common_logic
end
...
end
class PackagesController < ApplicationController
include CommonHelper
...
def download
some_logic_for_packages
common_logic
end
...
end
The third way to separate logic to ActiveSupport::Concern, and I think this choice is the best in this case.
module Commonable
extend ActiveSupport::Concern
...
def common_logic
common_logic1
common_logic2
common_logic3
end
...
end
class ServicesController < ApplicationController
include Commonable
...
def download
some_logic_for_services
common_logic
end
...
end
class PackagesController < ApplicationController
include Commonable
...
def download
some_logic_for_packages
common_logic
end
...
end
Can someone tell me the pros and cons of these three methods. or if any better way to solve, plese teach me. Thank you.
Upvotes: 2
Views: 705
Reputation: 5204
The Rails way is ActiveSupport::Concern
. You can too include it to ApplicationController
.
In some cases you can use Service way - if your logic does one thing you can move it to separate class. For example, we have shared code that check user's balance and notifies if it's negative.
If prefer to keep all services in app/services
folder, that need to add to autoload_path in application.rb
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/services)
Create class CheckUserBalance
class CheckUserBalance
def initialization(user)
@user = user
end
def call
unless @user.balance < 0
#notify about negative balance and change user's status
end
end
end
In controllers, we call this service.
CheckUserBalance.new(current_user).call
Upvotes: 1