我在下面有这个逻辑。两个控制器的动作内部具有相同的逻辑。 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制作方法并继承它。 但我认为这种方式可以用于胖的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 :: Concern的第三种方法,我认为在这种情况下这种选择是最好的。
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
有人可以告诉我这三种方法的优缺点。或者如果有更好的解决方法,请教我。谢谢。
答案 0 :(得分:1)
Rails方式是ActiveSupport::Concern
。您也可以将其添加到ApplicationController
。
在某些情况下,您可以使用服务方式 - 如果您的逻辑做了一件事,您可以将其移动到单独的类。 例如,我们提供了共享代码,用于检查用户的余额并通知其是否为负数。
如果希望将所有服务保留在app/services
文件夹中,则需要在application.rb中添加到autoload_path
config.autoload_paths += %W(#{config.root}/lib #{config.root}/app/services)
创建课程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