2017-04-10 43 views
0

我有下面的邏輯。兩個控制器在其動作內部具有相同的邏輯。 common_logic1 common_logic2 common_logic3,我想分開的共同邏輯,但不知道如何做到這一點。什麼是從控制器分離公共邏輯的最佳方式

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 

第一種方法是將方法創建到ApplicationController並繼承它。 但我認爲這種方式到了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 

第二種方法是將邏輯分離到助手模塊幷包含它。但我認爲幫手是從視圖分離邏輯。

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 

的第三種方式是邏輯分離開來的ActiveSupport ::關注,我覺得這個選擇是在這種情況下最好的。

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 

有人可以告訴我這三種方法的優缺點。或者如果有更好的解決辦法,請教我。謝謝。

回答

1

Rails的方式是ActiveSupport::Concern。你也可以將它包含到ApplicationController

在某些情況下,您可以使用服務方式 - 如果您的邏輯做了一件事,您可以將其移動到單獨的類。 例如,我們共享代碼來檢查用戶的餘額,並通知它是否爲負值。

如果希望保留所有服務app/services文件夾時,需要添加在application.rb中

config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/services)

到autoload_path創建類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 

在控制器中,我們稱這種服務。

CheckUserBalance.new(current_user).call 
+0

謝謝。有什麼情況可以使用ActiveSupport ::關注和服務層。我如何區分它們? –

+0

服務層用於業務邏輯。服務類可用於控制器,模型或耙子任務。當代碼具有與控制器相關的方法(重定向,參數...)時,請使用ActiveSupport :: Concern。 –

相關問題