0

我試圖重構一個搜索方法進入一個新的類,因爲我發現自己使用它在幾乎所有的模型在我的應用程序:如何使所有模型類都可以使用通用搜索代碼?

def self.text_search(query) 
    if query.present? 
     where("username @@ :q or email @@ :q", q: query).order(
     updated_at: :desc) 
    else 
     order(updated_at: :desc) 
    end 
    end 

的PARAMS usernameemail變化取決於模式,但我有3個模型,我用兩個不同的參數使用相同的功能。我的想法是使用一個裝飾,如:

class SearchModel < SimpleDelegator 

    def text_search(param1, param2, options={}) 
     query = options[:query] 
     if query.present? 
      __getobj__.where("#{param1} @@ :q or #{param2} @@ :q", q:query).order(updated_at: :desc) 
     else 
      order(updated_at: :desc) 
     end 
    end 
end 

我打電話SearchModel這樣的:

SearchModel.new(User.all).text_search('username', 'email', query: "admin") 

SearchModel.new(User.all).text_search('username', 'email') 

,它給我我想要的,但我不知道如果我使用的是裝飾者以正確的方式。這種類型的重構在Ruby的標準庫的其他部分會更合適,還是這是裝飾器的用途?

回答

1

使用裝飾器是比大多數人使用更復雜的方法,並導致複雜的調用語法。我會做這樣的:

module TextSearchSupport 
    def text_search(*args) 
    search_term = if args.last.responds_to(:[]) then args.pop[:query] end 
    query = 
     if search_term 
     where(args.map { |arg| "#{arg} @@ :q" }.join(' or '), q: query) 
     else 
     scoped 
     end 
    query.order(updated_at: :desc) 
    end 
end 

extend TextSearchSupport在每個需要的模式。然後,您可以在模型上調用text_search('foo','bar',查詢:'query')。

一對夫婦旁白的:

  • 它是更好的處理任意數量的字段,而不是硬編碼,所以我做了
  • 我想你想scoped而不是all避免運行查詢的時候了,所以我用了,但是你說你的版本在工作,所以不知道那裏發生了什麼。
+0

這真的很優雅 - 我想知道如何用我的方法來解決更多/更少的領域。 – user2936314

相關問題