<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>по стопам webkill&#039;а &#187; к</title>
	<atom:link href="http://blog.lukmus.ru/tag/%d0%ba/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.lukmus.ru</link>
	<description>это наш химический дом для печальных жителей Земли</description>
	<lastBuildDate>Sat, 21 Oct 2023 19:10:13 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>rails 3 + декоратор Draper</title>
		<link>http://blog.lukmus.ru/2012/12/18/rails-3-dekorator-draper/</link>
		<comments>http://blog.lukmus.ru/2012/12/18/rails-3-dekorator-draper/#comments</comments>
		<pubDate>Tue, 18 Dec 2012 04:31:21 +0000</pubDate>
		<dc:creator>lukmus</dc:creator>
				<category><![CDATA[ruby & ruby on rails]]></category>
		<category><![CDATA[draper]]></category>
		<category><![CDATA[ruby on rails 3]]></category>
		<category><![CDATA[декоратор]]></category>
		<category><![CDATA[к]]></category>

		<guid isPermaLink="false">http://blog.lukmus.ru/?p=1702</guid>
		<description><![CDATA[Захламлять модели своими методами в Rails-приложении это говнокод, это наверное знает каждый, в отличие от меня, однако, наличие дополнительных методов может существенно облегчить представление. Решить эту дилемму помогают декораторы. Ниже описан мой опыт знакомства с декораторами на примере гема Draper. Зачем нужен рефакторинг моделей и что это такое написано еще тут. А вот гем Draper. [...]]]></description>
			<content:encoded><![CDATA[<p>Захламлять модели своими методами в Rails-приложении это говнокод, это наверное знает каждый, <del datetime="2012-12-18T00:58:42+00:00"><a href="http://rubyclub.com.ua/messages/show/18571" rel="nofollow" target="_blank">в отличие от меня</a></del>, однако, наличие дополнительных методов может существенно облегчить представление. Решить эту дилемму помогают декораторы. Ниже описан мой опыт знакомства с декораторами на примере гема Draper.<br />
<img class="aligncenter size-full wp-image-1706" title="illusion" src="http://blog.lukmus.ru/wp-content/uploads/2012/12/illusion.jpg" alt="" width="517" height="291" /><span id="more-1702"></span><br />
Зачем нужен рефакторинг моделей и что это такое написано еще <a href="http://habrahabr.ru/post/158011/" rel="nofollow" target="_blank">тут</a>. А вот <a href="https://github.com/drapergem/draper" rel="nofollow" target="_blank">гем Draper</a>.</p>
<h2>установка</h2>
<p>Тут все как обычно. Добавляем в <code>Gemfile</code></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">gem 'draper'</pre></td></tr></table></div>

<p>и бандлим</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">bundle install</pre></td></tr></table></div>

<h2>эксплуатация</h2>
<h3>генерация</h3>
<p>Если модель генерируется после того как был установлен Draper, то декоратор создастся сам автоматически. Для ручной генерации декоратора есть команда:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">rails g decorator YourModel</pre></td></tr></table></div>

<p>После выполнения генерации можно увидеть директорию <code>app/decorators</code> где будет лежать файл <code>your_model_decorator.rb</code>. В этом файле и нужно прописывать дополнительные методы модели.</p>
<h3>ошибки</h3>
<p>Тут я не буду следовать инструкции со страницы гема т.к. она не соответствует реальности, по крайней мере с Rails 3.1.<br />
Итак, на данный момент существует файл декоратора модели YourModel <code>app/decorators/your_model_decorator.rb</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> YourModelDecorator <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationDecorator
  decorates <span style="color:#ff3333; font-weight:bold;">:your_model</span>
  <span style="color:#008000; font-style:italic;">#bla-bla-bla</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>И если сейчас запустить консоль, то вылетит ошибка:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">$ rails c
/home/username/ror/myapp/app/decorators/your_model_decorator.rb:<span style="">2</span>:in `': uninitialized constant ApplicationDecorator <span class="br0">&#40;</span>NameError<span class="br0">&#41;</span>
...</pre></td></tr></table></div>

<p>Конечно, можно создать файл <code>app/decorators/application_decorator.rb</code> как советует страница на гитхабе:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationDecorator <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Draper::Decorator</span>
  <span style="color:#008000; font-style:italic;"># your methods go here</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>но это вряд ли поможет, т.к. выскочит другая ошибка при запуске консоли:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">$ rails c
/home/username/ror/myapp/app/decorators/your_model_decorator.rb:<span style="">2</span>:in `': uninitialized constant Draper::Decorator <span class="br0">&#40;</span>NameError<span class="br0">&#41;</span>
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/draper-0.12.0/lib/draper/system.rb:<span style="">9</span>:in `block in load_app_local_decorators'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/draper-0.12.0/lib/draper/system.rb:<span style="">9</span>:in `each'
from /usr/local/rvm/gems/ruby-1.9.2-p290/gems/draper-0.12.0/lib/draper/system.rb:<span style="">9</span>:in `load_app_local_decorators'
...</pre></td></tr></table></div>

<p>Пошарясь немного по файлам в директории <code>/usr/local/rvm/gems/ruby-1.9.2-p290/gems/draper-0.12.0/lib/draper/</code>, а конкретнее в файле <code>/usr/local/rvm/gems/ruby-1.9.2-p290/gems/draper-0.12.0/lib/draper/base.rb</code> становится ясно, что <code>app/decorators/application_decorator.rb</code> надо привести к виду:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationDecorator <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Draper::Base</span>
  <span style="color:#008000; font-style:italic;"># your methods go here</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>И тут все ошибки резко пропадают.</p>
<h3>использование</h3>
<p>Теперь в декоратор нужно перенести лишние методы из модели. Для того чтобы экземпляры модели пополнились методами из декоратора при их использовании в контроллере или еще где-либо нужно делать так:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">&gt; your_model_exemplar=YourModel.first
&gt; your_model_exemplar.new_method_which_is_in_decorator
NoMethodError: undefined method `new_method_which_is_in_decorator' for #
&gt; your_model_exemplar=YourModelDecorator.new YourModel.first
&gt; your_model_exemplar.new_method_which_is_in_decorator
=&gt; &quot;it really works&quot;
&gt; your_model_exemplars=YourModelDecorator.decorate YourModel.first<span class="br0">&#40;</span><span style="">10</span><span class="br0">&#41;</span>
&gt; your_model_exemplars.first.new_method_which_is_in_decorator
=&gt; &quot;it really works&quot;</pre></td></tr></table></div>

<p>Для коллекции обязательно использовать метод <code>decorate</code>, для единичного экземпляра можно и <code>new</code>, и <code>decorate</code>. Сказка про <code>decorate_collection</code> для коллекции, которая написана на гитхабе это всего лишь сказка, ее рекомендации не работают в реальном мире.</p>
<h3>хелперы в декораторе</h3>
<p>Офстраница на гитхабе советует задействовать хелперы через <code>helpers</code> и сокращенную форму <code>h</code> или без дополнительных примочек просто подключив модуль <code>include Draper::LazyHelpers</code> (ниже дезинформация с https://github.com/drapergem/draper):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ArticleDecorator <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Draper::Decorator</span>   
  <span style="color:#9966CC; font-weight:bold;">def</span> published_at     
    date = h.<span style="color:#9900CC;">content_tag</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:span</span>, article.<span style="color:#9900CC;">published_at</span>.<span style="color:#9900CC;">strftime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%A, %B %e&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">squeeze</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'date'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    time = h.<span style="color:#9900CC;">content_tag</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:span</span>, article.<span style="color:#9900CC;">published_at</span>.<span style="color:#9900CC;">strftime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;%l:%M%p&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'time'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    h.<span style="color:#9900CC;">content_tag</span> <span style="color:#ff3333; font-weight:bold;">:span</span>, date <span style="color:#006600; font-weight:bold;">+</span> time, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'created_at'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>У меня ничего из предложенного не прокатило, зато неожиданно прокатил способ с <code>helper</code>.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> YourModelDecorator <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationDecorator
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Draper::LazyHelpers</span> <span style="color:#008000; font-style:italic;">#по идее должен избавить от явного объявления helper, но нет</span>
  decorates <span style="color:#ff3333; font-weight:bold;">:your_model</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_helpers
    content_tag <span style="color:#ff3333; font-weight:bold;">:div</span>, <span style="color:#996600;">&quot;it really works&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_helpers_via_h
    h.<span style="color:#9900CC;">content_tag</span> <span style="color:#ff3333; font-weight:bold;">:div</span>, <span style="color:#996600;">&quot;it really works&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>    
  <span style="color:#9966CC; font-weight:bold;">def</span> test_helpers_via_helpers
    helpers.<span style="color:#9900CC;">content_tag</span> <span style="color:#ff3333; font-weight:bold;">:div</span>, <span style="color:#996600;">&quot;it really works&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>   
  <span style="color:#9966CC; font-weight:bold;">def</span> may_be_that_is_working?
    helper.<span style="color:#9900CC;">content_tag</span> <span style="color:#ff3333; font-weight:bold;">:div</span>, <span style="color:#996600;">&quot;Hallelujah!&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>  
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="code"><pre class="" style="font-family:monospace;">&gt; your_model_exemplar=YourModelDecorator.new YourModel.first
&gt; your_model_exemplar.test_helpers
NoMethodError: undefined method `content_tag' for #
&gt; your_model_exemplar.test_helpers_via_h
NoMethodError: undefined method `content_tag' for nil:NilClass
&gt; your_model_exemplar.test_helpers_via_helpers
NoMethodError: undefined method `content_tag' for nil:NilClass
&gt; your_model_exemplar.may_be_that_is_working?
=&gt; &quot;&lt;div&gt;Hallelujah!&lt;/div&gt;&quot;</pre></td></tr></table></div>

<p>Собственно все. Быть может все эти ошибки из-за того, что у меня ruby 1.9.2, а гем писался для 1.9.3 или рельсы у меня старые, а может просто доки у гема что-то типа квеста.<br />
<meta property="og:image" content="http://blog.lukmus.ru/wp-content/uploads/2012/12/illusion.jpg" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lukmus.ru/2012/12/18/rails-3-dekorator-draper/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
