#212
18 октября 2010
1 коммент
Рефакторинг и динамическое делегирование
В этом выпуске мы займемся рефакторингом набора запросов Active Record с условиями, используя динамическую делегацию.
Скачать
(22.5 МБ, 8:19)
Источники
- Searchlogic (альтернативное решение)
- Исходный код выпуска
# rails console
Product.search({}).class
Object.instance_methods
BasicObject.instance_methods
# products_controller.rb
products</span> = <span class="co">Product</span>.search(params) <span class="c"># models/product.rb</span> <span class="r">def</span> <span class="pc">self</span>.<span class="fu">search</span>(params) products = scope_builder products.where(<span class="s"><span class="dl">"</span><span class="k">name like ?</span><span class="dl">"</span></span>, <span class="s"><span class="dl">"</span><span class="k">%</span><span class="dl">"</span></span> + params[<span class="sy">:name</span>] + <span class="s"><span class="dl">"</span><span class="k">%</span><span class="dl">"</span></span>) <span class="r">if</span> params[<span class="sy">:name</span>] products.where(<span class="s"><span class="dl">"</span><span class="k">price >= ?</span><span class="dl">"</span></span>, params[<span class="sy">:price_gt</span>]) <span class="r">if</span> params[<span class="sy">:price_gt</span>] products.where(<span class="s"><span class="dl">"</span><span class="k">price <= ?</span><span class="dl">"</span></span>, params[<span class="sy">:price_lt</span>]) <span class="r">if</span> params[<span class="sy">:price_lt</span>] products <span class="r">end</span> <span class="r">def</span> <span class="pc">self</span>.<span class="fu">scope_builder</span> <span class="co">DynamicDelegator</span>.new(scoped) <span class="r">end</span> <span class="c"># lib/dynamic_delegator.rb</span> <span class="r">class</span> <span class="cl">DynamicDelegator</span> < <span class="co">BasicObject</span> <span class="r">def</span> <span class="fu">initialize</span>(target) <span class="iv">target = target
end
def method_missing(args, &block)
result = @target.send(args, &block)
target</span> = result <span class="r">if</span> result.kind_of? <span class="iv">target.class
result
end
end


