2016-05-30 11 views
1

私は以下の検索クラスメソッドを用意しています。このメソッドは、多数のパラメータを取り、要求を作成します。クラスの継承でNilを処理するRails

def self.search(agent, params) 
    RealPropertySale.where(id: available_ids) 
         .joins(:address) 
         .by_state(state) 
         .by_suburb(suburb) 
         .by_post_code(post_code) 
         .by_country(country) 
         .paginate(page: page) 
end 

def self.by_state(state) 
    where(addresses: {state: state}) 
end 

def self.by_suburb(suburb) 
    where(addresses: {suburb: suburb}) 
end 

def self.by_post_code(post_code) 
    where(addresses: {post_code: post_code}) 
end 

def self.by_country(country) 
    where(addresses: {country: country}) 
end 

私のカスタムクラスのメソッドの1つ、たとえば、 self.by_country(country)はnilを返し、どのようなparam/sが存在してもクエリが継続するようにします。 paramsが空白だが、クエリが失われてクラスが返されてエラーが発生した場合、自己復帰を試みた。

+0

'self.by_country(country)'は 'nil'を返すべきではありません。これは、空のセットを持つ 'ActiveRecord :: Relation'のインスタンスを返さなければなりません。 – Uzbekjon

+0

適切な基準を持つクエリのみを連結してください。 'country'が指定されていない場合、' by_country(country) 'を連想させると、行のないSQL文が生成され、それ以外の場合は有効な条件でクエリが失敗します。 'self.search'で呼び出すチェーンメソッドを選択して、正しく動作させることができます。 –

答えて

2

@Michael Gaskillには、最終的なクエリに実際に影響を与えるスコープ(つまり、意味のあるパラメータを持つスコープ)を呼び出すだけでよいことに同意します。

あなたがnilパラメータを無視してスコープを主張する場合は、あなたがそれらを(undocumentedが、有用な方法である)の代わりにcurrent_scopeを返す作ることがあります。

def self.by_state(state) 
    return current_scope if state.nil? 
    where(addresses: {state: state}) 
end 
+0

@Michael Gaskillに同意し、それに応じてコードを調整しました。あなたの答えに関して、私はあなたが 'all'か' current_scope'のいずれかであることがわかりました。 –

1

我々はそれを破壊することにより、同様の何かをしましたように:

response = RealPropertySale.where(id: available_ids) 
        .joins(:address) 
response = response.by_state(state)   if state 
response = response.by_suburb(suburb)  if suburb 
response = response.by_post_code(post_code) if post_code 
response = response.by_country(country)  if country 
response = response.paginate(page: page)  if page 

私は読みやすさが好きです。私は必要に応じて多くの部分に分解しようとしますが、これはあなたのビジネスロジックに適応する必要があります。たとえば、郊外が提供されているかどうかを確認するのが適切かどうかは分かりません。