我的搜索方法很臭臃腫,我需要一些幫助來重構它。我是新來的紅寶石,而我還沒有想出如何有效地利用它,導致臃腫的方法是這樣的:如何在Rails模型中重構複雜的搜索邏輯
# discussion.rb
def self.search(params)
# If there is a search query, use Tire gem for fulltext search
if params[:query].present?
tire.search(load: true) do
query { string params[:query] }
end
# Otherwise grab all discussions based on category and/or filter
else
# Grab all discussions and include the author
discussions = self.includes(:author)
# Filter by category if there is one specified
discussions = discussions.where(category: params[:category]) if params[:category]
# If params[:filter] is provided, user it
if params[:filter]
case params[:filter]
when 'hot'
discussions = discussions.open.order_by_hot
when 'new'
discussions = discussions.open.order_by_new
when 'top'
discussions = discussions.open.order_by_top
else
# If params[:filter] does not match the above three states, it's probably a status
discussions = discussions.order_by_new.where(status: params[:filter])
end
else
# If no filter is passed, just grab discussions by hot
discussions = discussions.open.order_by_hot
end
end
end
STATUSES = {
question: %w[answered],
suggestion: %w[started completed declined],
problem: %w[solved]
}
scope :order_by_hot, order('...') DESC, created_at DESC")
scope :order_by_new, order('created_at DESC')
scope :order_by_top, order('votes_count DESC, created_at DESC')
這是可以通過一個過濾(或者不是)一個模型的探討類別:question
,problem
,suggestion
。
所有討論或單個類別可以進一步篩選hot
,new
,votes
或status
。狀態是模型中的一個散列,它取決於類別具有多個值(只有在出現params [:category]時纔會顯示狀態過濾器)。
複雜的問題是使用輪胎
一個全文檢索功能,但我的控制器看起來不錯,整潔:
def index
@discussions = Discussion.search(params)
end
我可以幹這件事/重構它一點點,也許使用元編程或塊?我設法從控制器中提取出來,但後來用完了想法。我不知道Ruby是否足夠進一步採取這一做法。
完美。謝謝。我結束了這個:http://pastie.org/5166966 - 至於常數,他們在頂部;爲了清晰起見,我只是將它們粘貼在底部。 – dee
PS:不過,不確定你的意思是'返回'腳'if'。而重複的「討論=討論」,我把它拿出來了,但是我必須把它留給'where'從句,否則沒有什麼東西會回來。 – dee
@dee - 答案已更新以回覆您的評論。 –