我有下面的代码可以工作,但是我希望它更加干燥和优雅。感觉很丑,有很多代码味道。
理想情况下,我也不想使用CASE语句,因为那样也不太红宝石。
if @property_status.eql? :rent
if @property_type.eql? :residential
@results = @search.results.for_rent.residential.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
elsif @property_type.eql? :commercial
@results = @search.results.for_rent.commercial.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
else
@results = @search.results.for_rent.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
end
elsif @property_status.eql? :sale
if @property_type.eql? :residential
@results = @search.results.for_sale.residential.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
elsif @property_type.eql? :commercial
@results = @search.results.for_sale.commercial.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
else
@results = @search.results.for_sale.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
end
else
@results = @search.results.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
end
有想法吗?
答案 0 :(得分:4)
首先认识到这一点:
@results = @search.results.for_rent.residential.order("#{ @sort_by } #{ @sort_order }").all.paginate(page: @page, per_page: @per_page)
等效于:
@results = @search.results
@results = @results.for_rent
@results = @results.residential
@results = @results.order(@sort_by => @sort_order).paginate(page: @page, per_page: @per_page)
假设@sort_by
和@sort_order
始终是设置好的。重要的是,您可以逐段构建查询,然后根据实例变量选择要添加的段。您可以添加几个简单的助手:
def add_property_status_to(query)
case @property_status
when :rent, :sale
query.public_send("for_#{@property_type}")
else
query
end
end
def add_property_type_to(query)
case @property_type
when :residential, :commercial
query.public_send(@property_type)
else
query
end
end
然后说这样的话:
query = @search.results
query = add_property_status_to(query)
query = add_property_type_to(query)
@results = query.order(@sort_by => @sort_order).paginate(page: @page, per_page: @per_page)
您可以将add_property_status_to
和add_property_type_to
方法视为本地一次性使用范围。如果您需要在多个地方使用它们,则可以使它们成为@search.results
上的类方法,并说出类似这样的话:
query = @search.results
query = query.with_property_status(@property_status)
query = query.with_property_type(@property_type)
@results = query.order(@sort_by => @sort_order).paginate(page: @page, per_page: @per_page)
答案 1 :(得分:2)
我没有对其进行测试,但我认为符合以下要求:
def results
return results_for_rent if for_rent?
return results_for_sale if for_sale?
default_results
end
def for_rent?
@property_status.eql? :rent
end
def for_sale?
@property_status.eql? :sale
end
def default_results
@results = @search.results.order("#{ @sort_by } #{ @sort_order
}").all.paginate(page: @page, per_page: @per_page)
end
def results_for_rent
if [:residential, :commercial].includes?(@property_type)
results(@property_type, type: :for_rent)
return
end
@results = @search.results.for_rent.commercial.order("#{ @sort_by } #{
@sort_order }").all.paginate(page: @page, per_page: @per_page)
end
def results_for_sale
if [:residential, :commercial].includes?(@property_type)
results(kind, type: :for_sale)
return
end
@results = @search.results.for_sale.order("#{ @sort_by } #{ @sort_order
}").all.paginate(page: @page, per_page: @per_page)
end
def results(kind:, type: )
@results = @search.results.send(kind).send(type).order("#{ @sort_by } #{
@sort_order }").all.paginate(page: @page, per_page: @per_page)
end
您也可以重构.all.pagination部分,该部分相同,但是您可以理解。您还可以通过添加一个参数来重构results_for_rent
和results_for_sale
方法