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

search_params(に渡されたときにスプラットの必要性を指摘してくれた@ajcodezに感謝し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

これが私がそれをする方法です。フィールドを定数として定義することもできます。

FIELDS = [:city, :country]

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

フィールドの感嘆符に注意してください。Hash#slice:http ://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Hash/Slice.html

于 2012-12-06T01:10:20.790 に答える
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

長所:

+拡張可能(他のモデルのサポートも)

+テスト可能(DBにほとんどヒットしなくても)

+再利用可能

短所:

-少し多くのコード

于 2012-12-06T04:25:12.067 に答える