我有两个带有不同身份验证方案的控制器, 但他们几乎一样。
封装rails的最佳方法是什么? 另一个类或助手中的控制器的逻辑?
样品:
def ControllerA < BasicAuthController
def create
blablacode
end
end
def ControllerB < TokenAuthController
def create
blablacode
end
end
这样做的正确方法是什么?用代码创建一个模型? 创建一个帮手?其他
答案 0 :(得分:0)
我这样做:
#app/services/my_app/services/authentication.rb
class MyApp::Services::Authentication
class < self
def call(params={})
new(params).call
end
end # Class Methods
#==============================================================================================
# Instance Methods
#==============================================================================================
def initialize(params)
@params = params
end
def call
... do a lot of clever stuff
... end by returning true or false
end
private
def params() @params end
end
然后:
class FooController < ApplicationController
before_action :authenticate
def authenticate
redirect_to 'some_path' unless MyApp::Services::Authenticate.call(with: 'some_params')
end
end
答案 1 :(得分:0)
为什么不为单个控制器启用这两种方案?特别是如果唯一的区别是身份验证。您可以有两个app/controllers/concerns
来封装两种身份验证方法,include Auth1
和include Auth2
用于单个控制器,它只负责它管理的任何资源。
否则,服务是封装控制器逻辑的最佳方法。
在services
文件夹中创建一个名为app
的文件夹,并在此处编写PORO课程。假设您的应用中有几个地方可以通过make Stripe支付费用。
# app/services/stripe_service.rb
module StripeService
def customer(args)
...
end
def pay(amount, customer)
...
end
def reverse(stripe_txn_id)
...
end
end
# controller
StripeService.customer(data)
=> <#Stripe::Customer>
或者如果你只需要做一件事。
# app/services/some_thing.rb
module SomeThing
def call
# do stuff
end
end
# controller
SomeThing.call
=> # w/e
如果您需要具有多个reponsibilities的对象,则可以创建一个类。
class ReportingService
def initialize(args)
...
end
def query
...
end
def data
...
end
def to_json
...
end
end
https://blog.engineyard.com/2014/keeping-your-rails-controllers-dry-with-services
答案 2 :(得分:0)
最简单的方法是创建一个模块,然后将include
放入其他控制器:
module ControllerMixin
def create
blablacode
end
end
然而,剩下的问题是将此代码放在何处使其适用于Rails自动加载器,因为它需要在控制器之前加载。一种方法是将模块写入lib/
目录中的文件,然后将其添加到自动加载路径(请参阅auto-loading-lib-files-in-rails-4
答案 3 :(得分:0)
简短回答,我选择创建一个帮助者。
&#xA;&#xA;来自答案中的所有建议
&#xA;&#xA; 创建一个模块:&#xA;看起来是正确的但是在 app
目录下面有逻辑并不合适。这不是一个外部模块或库,但&#xA;与我的应用程序的逻辑非常相关的东西。
在一个控制器中集成不同的身份验证:&#xA;是一个很好的建议,但我必须改变我的所有逻辑应用程序。
创建帮助:&#xA;在我看来,更好的解决方案,我有一个帮助程序的代码,和& #xA;在app目录中,非常接近其他逻辑。