1

这段代码感觉不对。我试图让我的控制器变瘦,我觉得控制器动作中的逻辑太多了。

组织此代码的更好方法是什么?

def search
    where_obj = {:status => 1}

    if params[:city].present?
        where_obj.merge! :city => params[:city]
    end

    if params[:county].present?
        where_obj.merge! :county => params[:county]
    end

    ## THERE WILL BE MANY MORE IF STATEMENTS HERE DUE TO GROWING SEARCH FORM

    @person = Person.where(where_obj)
end

随着搜索表单的增长,此控制器操作也会增长。我怎样才能让我的控制器变瘦?

4

4 回答 4

2

怎么样:

def search
  query = { :status => 1 }.merge(params.select { |k,_| [:city, :country].include?(k) })
  @person = Person.where(query)
end

或者使用(在 Rails 中)slice提供的方法的更简单的版本:ActiveSupport

def search
  query = { :status => 1 }.merge(params.slice(:city, :country))
  @person = Person.where(query)
end

如果您将有一堆不同的参数来选择性地包含,那么您可以像这样对它们进行分组:

def search
  search_params = [:city, :country, :continent, ...]
  query = { :status => 1 }.merge(params.slice(*search_params))
  @person = Person.where(query)
end

(感谢@ajcodez 指出search_params在传递给时需要 splat slice。)

于 2012-12-06T00:00:58.477 回答
1
def search
  @person = Person.where({status: 1}.merge(params).select{|_, v| v.present?})
end
于 2012-12-06T00:12:45.140 回答
1
# controller
def search
  @person = PersonSearch.new(params).result
end


# lib/person_search.rb
class PersonSearch

  attr_accessor :params

  SUPPORTED_FIELDS = [:city, :country]

  def initialize(params)
    @params = params
  end

  def result
    Person.where conditions
  end

  private

  def conditions
    conditions = default_conditions

    SUPPORTED_FIELDS.each do |field|
      conditions.merge!(field => params[field]) if params[field]
    end

    conditions
  end

  def default_conditions
    { :status => 1 }
  end

end

不断增长的搜索形式?将更多属性添加到SUPPORTED_FIELDS.

优点:

+可扩展(甚至支持其他型号)

+可测试(即使大部分情况下都不会影响您的数据库)

+可重复使用

缺点:

-更多的代码

于 2012-12-06T04:25:12.067 回答
1

这就是我将如何做到的。您也可以将字段定义为常量。

FIELDS = [:city, :country]

def search
  query_params = params.slice(*FIELDS).reject { |_,val| val.blank? }
  query_params[:status] = 1
  @person = Person.where query_params
end

注意字段上的 splat。哈希#slice:http ://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Hash/Slice.html

于 2012-12-06T01:10:20.790 回答