如何处理实例变量赋值的多个条件

时间:2015-01-05 08:04:46

标签: ruby-on-rails ruby ruby-on-rails-4 instance-variables

我的控制器中有以下内容,它将根据Ajax调用收到的params分配不同的结果集合。它很乱,我想在我的索引控制器中调用一个包含所有逻辑的函数而不是所有这些函数

class PublicController < ApplicationController
  def index
    if params[:literacy_param].present?
      @skills = Skill.search(params)
    elsif params[:numeracy_param].present?
      @skills = Skill.numeracy_default_params
    elsif params[:numeracy_number_skills].present?
      @skills = Skill.numeracy_number_skills
    elsif params[:numeracy_measuring_skills].present?
      @skills = Skill.numeracy_measuring_skills
    elsif params[:numeracy_data_skills].present?
      @skills = Skill.numeracy_data_skills
    else
      @skills = Skill.default_params
    end
  end
end

我有点不确定如何设置我的功能,以便它可以读取正在发送的参数,

到目前为止,我已经提出了这个问题

private
 def skills(params)
   if params[:literacy_param].present?
     @skills = Skill.search(params)
   elsif params[:numeracy_param].present?
     @skills = Skill.numeracy_default_params
   elsif params[:numeracy_number_skills].present?
    @skills = Skill.numeracy_number_skills
   elsif params[:numeracy_measuring_skills].present?
    @skills = Skill.numeracy_measuring_skills
   elsif params[:numeracy_data_skills].present?
    @skills = Skill.numeracy_data_skills
   else
    @skills = Skill.default_params
   end    
 end

然后在我的索引动作中我会做

@skills = skills(params)

这会是一种有效的方式吗?

由于

3 个答案:

答案 0 :(得分:3)

你可以这样做

class PublicController < ApplicationController
  def index
    skills = ['literacy_param', 'numeracy_param', 'numeracy_number_skills', 'numeracy_measuring_skills', 'numeracy_data_skills']
    common_in_params = (skills & params).first
    @skills = common_in_params.present? ? (common_in_params.eql?('literacy_param') ? Skill.search(params) : Skill.send(common_in_params)) : Skill.default_params                
  end
end

您可以在初始化程序中定义skills数组以获得可重用性

答案 1 :(得分:1)

这样做的一种方法是:

def skills(params)
  set_of_skills = params.slice(
    :numeracy_param,
    :numeracy_number_skills,
    :numeracy_measuring_skills,
    :numeracy_data_skills,
  ).first

  @skills = if params[:literacy_param]
    Skill.search(params)
  elsif set_of_skills
    Skill.public_send(set_of_skills)
  else
    Skill.default_params
  end
end

我还建议将其解压缩到lib/文件夹中,并进行单元测试。因此,在您的控制器中,您可以执行以下操作:

def index
  @skills = SkillSearch.new(params).search
end

答案 2 :(得分:1)

我现在可以想到两种方法:

  1. 用一把独特的钥匙包住params。与params = { :keyword => :literacy_param }中一样,然后使用此唯一键来标识正确的操作。
  2. 在你 skill.rb

    def self.filter(params)
      if params[:keyword] == :literacy_param
        search(params)
      elsif available_filters.include?(params[:keyword])
        public_send(params[:keyword])
      else
        default_params
      end
    end
    
    private
    
      def self.available_filters
        %i{numeracy_default_params numeracy_number_skills numeracy_measuring_skills numeracy_data_skills}
      end
    

    考虑到:numeracy_param而不是:numeracy_default_params,您可以在:keyword密钥中发送elsif。否则,您必须在filter方法中另外制作index

    然后在您的def index @skilles = Skill.filter(params) end 方法中:

    SkillSeacrher
    1. 您可以创建一个单独的过滤器类,这是一个可扩展的解决方案,以防您需要进行复杂的搜索查询和过滤。
    2. 让我们在你的 app / models / skill_searcher.rb 中调用它class SkillSearcher attr_reader :keyword def initialize(keyword) @keyword = keyword end def filter if keyword == :literacy_param Skill.search(params) elsif available_filters.include?(keyword) Skill.public_send(keyword) else Skill.default_params end end private def self.available_filters %i{numeracy_default_params numeracy_number_skills numeracy_measuring_skills numeracy_data_skills} end end

      index

      然后在def index @skills = SkillSearcher.new(params[:keyword]).filter end 方法中:

      filter

      但是,您可以对def filter if keyword == :literacy_param Skill.search(params) else Skill.public_send(available_filters.include?(keyword) ? keyword : :default_params) end end 方法进行一次更改(取决于您的口味):

      params

      并且,如果你有所有这些方法接受def filter Skill.public_send(available_filters.include?(keyword) ? keyword : :default_params, params) end 作为参数,那么它会更加光滑:

      {{1}}