5

以下是我Concerns::V1::PlanFinding对控制器的关注。根据base控制器和动作,它调用set_plan

 extend ActiveSupport::Concern
  attr_accessor :plan, :custom_key

  included do |base|
    actions = case base.to_s
              when "Api::V1::PlansController"
                [:show, :total_prices, :update]
              when "Dist::PlansController"
                [:show, :total_prices, :flight_info]
              end

    if actions.present?
      before_action :set_plan, only: actions
    else
      before_action :set_plan
    end
  end

  def set_plan
    @plan = Model.find('xxx')
    @custom_key = params[:custom_key] || SecureRandom.hex(10)
  end

以下是我提出问题的一个控制器:

class Dist::PlansController
   include ::Concerns::V1::PlanFinding

这运行良好。但是关注代码与控制器太粘了base

我的问题是:由于我们不能only在控制器中使用如下选项。如何实现我自己only的包含选项,或找到一种新方法将base控制器与关注点分离:

include Concerns::V1::PlanFinding, only: [:show]
4

1 回答 1

2

AFAIK 这是不可能的。我使用以下方法:

PLAN_FINDING_USE = [:show]
include Concerns::V1::PlanFinding

included do |base|
  actions = base.const_defined?('PLAN_FINDING_USE') &&
            base.const_get('PLAN_FINDING_USE')

  if actions.is_a?(Array)
    before_action :set_plan, only: actions
  else
    before_action :set_plan
  end
end
于 2017-06-28T11:24:06.730 回答