<?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>fxposter&#039;s wave &#187; Работа</title>
	<atom:link href="http://blog.fxposter.org/category/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.fxposter.org</link>
	<description>Stories about Ruby, JavaScript, Objective-C and other cool tools</description>
	<lastBuildDate>Sun, 25 Jul 2010 08:46:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Установка gem-ов в пользовательскую директорию</title>
		<link>http://blog.fxposter.org/2010/07/07/install-gems-to-user-directory/</link>
		<comments>http://blog.fxposter.org/2010/07/07/install-gems-to-user-directory/#comments</comments>
		<pubDate>Wed, 07 Jul 2010 20:15:19 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=808</guid>
		<description><![CDATA[Есть такая фича в Rubygems, как установка гем-ов в директорию пользователя ~/.gem, если gem install запускается без sudo и, соответственно, у пользователя нет разрешения установить что-либо в дефолтную директорию. В Rubygems до версии 1.3.6 это решалось просто - автоматически. Т.е. если вы вместо sudo gem install пишете gem install - вам выдается warning, но гем [...]]]></description>
			<content:encoded><![CDATA[<p>Есть такая фича в <a href="http://rubyforge.org/projects/rubygems/">Rubygems</a>, как установка гем-ов в директорию пользователя ~/.gem, если <code>gem install</code> запускается без sudo и, соответственно, у пользователя нет разрешения установить что-либо в дефолтную директорию.</p>
<p>В Rubygems до версии 1.3.6 это решалось просто - автоматически. Т.е. если вы вместо <code>sudo gem install</code> пишете <code>gem install</code> - вам выдается warning, но гем успешно устанавливается:</p>
<pre><code>[fxposter@kitty ~]$ gem install haml
WARNING:  Installing to ~/.gem since /usr/lib/ruby/gems/1.8 and
/usr/bin aren't both writable.
Successfully installed haml-3.0.13
1 gem installed
Installing ri documentation for haml-3.0.13...
Installing RDoc documentation for haml-3.0.13...</code></pre>
<p>Вроде бы всё замечательно. Но с версии 1.3.6 это дефолтное поведение изменилось, и при обновлении с помощью <code>gem update --system</code> об этом честно пишется:</p>
<blockquote><p>&#8211;user-install is no longer the default.  If you really liked it, see Gem::ConfigFile to learn how to set it by default.  (This change was made in 1.3.6)</p></blockquote>
<p>Но кто реально читают все эти тексты? Да и не все обновляют Rubygems таким образом. В нашем случае произошла смена сервера. Причем на старом сервере стояла старая версия <a href="http://www.rubyenterpriseedition.com/">Ruby Enterprise Edition</a> и дефолтные Rubygems 1.3.5. На новом же серваке наши бравые админы опять всё &#8220;покомпилили&#8221; и вместе с REE у нас там обновился и Rubygems - теперь там стояла версия 1.3.7. И&#8230; сначала отвалился деплой, т.к. по умолчанию rake gems:install у нас там не включен. Запустили rake gems:install - не работает. Запустили gem install - не работает. Всё просто замечательно.</p>
<p>Разбирались долго. Сначала думали на админов, которые в рельсах плохо шарят и думали, что они там &#8220;понастраивали&#8221;. Кстати, понастраивали они действительно знатно - скомпилированный REE почему-то стоит поверх стандартного Ruby 1.8.5 (у нас там CentOS 5, в ближайшем времени переезжаем на <a href="http://aws.amazon.com/ec2/">Amazon EC2</a> на Ubuntu). Но это неважно. После долгого разговора с админом и ковыряния серваков я чисто случайно обратил внимание на разные версии Rubygems. Заподозрил неладное. Обновил их на старом серваке на 1.3.7 и&#8230; получил сообщение, написанное выше. Отлично. Теперь осталось восстановить поведение старых Rubygems.</p>
<p>В итоге всё оказалось довольно просто. В файл ~/.gemrc нужно дописать следующую строку: <code>"install: --user-install"</code>. После чего мой .gemrc стал выглядеть так:</p>
<pre><code>[waysgo@web-waysgo ~]$ cat .gemrc
---
:benchmark: false
:update_sources: true
:sources:
- http://rubygems.org/
- http://gems.github.com/
:bulk_threshold: 1000
:verbose: true
:backtrace: false
install: --user-install</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/07/07/install-gems-to-user-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Особенности работы jQuery.live()</title>
		<link>http://blog.fxposter.org/2010/06/16/jquery-live-method/</link>
		<comments>http://blog.fxposter.org/2010/06/16/jquery-live-method/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 23:21:26 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[event bubbling]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[live]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=787</guid>
		<description><![CDATA[На работе столкнулись с &#8220;особенностью&#8221; работы jQuery.live(), на которую хотелось бы обратить внимание, потому как, судя по всему, отнюдь не все о ней знают (и в результате чего пишут неработающий код). Итак, простой пример - навешивание двух событий на один и тот же элемент: &#60;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&#62; &#60;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>На <a href="http://waysgo.com/">работе</a> столкнулись с &#8220;особенностью&#8221; работы <a href="http://api.jquery.com/live/">jQuery.live()</a>, на которую хотелось бы обратить внимание, потому как, судя по всему, отнюдь не все о ней знают (и в результате чего пишут неработающий код).</p>
<p>Итак, простой пример - навешивание двух событий на один и тот же элемент:</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").bind("click", function(e) {
      alert("a");
      return false;
    });
    $("a").bind("click", function(e) {
      alert("b");
      return false;
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>Пример можно посмотреть <a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test.html">здесь</a>. В результате клика на ссылку - получаем 2 alert-а, всё хорошо, ожидаемо и предсказуемо.</p>
<p>Переписываем код для работы с jQuery.live(). Для тех, кто в танке - live() вешает событие не на сам элемент, а на document. В результате <a href="http://www.quirksmode.org/js/events_order.html">bubbling-а</a> событие, которое произошло над каким-либо элементом поднимается вверх по <a href="http://ru.wikipedia.org/wiki/Document_Object_Model">DOM-дереву</a> и соответственно вызывает обработчики всех элементов, которые оно встретит. Если вы и этого не знали - то вам не нужно читать мой блог, а пора идти и покупать книгу по JavaScript-у (мне, кстати, тоже давно пора, но всё никак не соберусь). Итак, в конце концов событие доходит до document-а и обработчики вызываются у него. Обработчик, который устанавливает jQuery.live() проверяет - соответствует ли event.target (а именно здесь хранится обьект DOM-дерева, с которым произошло событие) соответствующему селектору (в данном случае - это селектор &#8220;a&#8221;) и если соответствует - то выполняет обработчик.</p>
<p>Преимущества и недостатки - это тема отдельной статьи. Если не уклонятся в сторону оптимизации, то основным преимуществом, на мой взгляд, является тот факт, что обработчики, навешенные live()-ом будут запускаться даже для элементов, которые были динамически добавлены на страницу, в отличии от <a href="http://api.jquery.com/bind/">bind()</a>-обработчиков, которые на эти элементы нужно будет навешивать вручную (если непонятно, почему это работает именно так - читаем предыдущий абзац, если все равно непонятно - идем покупать всё ту же книгу).</p>
<p>Далее - зачем нужен &#8220;return false&#8221; в конце обработчика? Он предотвращает от того, чтобы вызывалось действие по умолчанию (в данном случае - переход по ссылке и событие не поднималось выше). Чаще всего JS-разработчики вообще не думают о bubbling-е и под &#8220;return false&#8221; понимают только &#8220;отмену действия по умолчанию&#8221;, ну или они вообще не знают, что именно происходит и пишут &#8220;return false&#8221;, потому что так работает.</p>
<p>Такое отношение jQuery частенько прощает. Но не в случае с live()-методом. Попробуем запустить следующий <a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test2.html">пример</a>:</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      return false;
    });
    $("a").live("click", function(e) {
      alert("b");
      return false;
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>В результате клика теперь выскакивает только один alert. Пора обратится к <a href="http://api.jquery.com/live/">документации</a>:</p>
<blockquote><p># To stop further handlers from executing after one bound using .live(), the handler must return false. Calling .stopPropagation()  will not accomplish this.</p></blockquote>
<p>Хаха. В данном случае jQuery интерпретирует false &#8220;несколько иначе&#8221;. :)</p>
<p>Для того, чтобы &#8220;пофиксить&#8221; подобный баг нужно обратится все к тому же bubbling-у и обработке событий и сделать именно то, что предполагается разработчиком - &#8220;отменить действие по умолчанию&#8221;. Это делается с помощью метода <a href="https://developer.mozilla.org/en/DOM/event.preventDefault">event.preventDefault()</a> (<a href="http://blog.fxposter.org/wp-content/uploads/2010/06/test3.html">пример</a>):</p>
<pre><code class="html">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
  &lt;meta http-equiv="Content-type" content="text/html; charset=UTF-8" /&gt;
  &lt;title&gt;jQuery.live() test page&lt;/title&gt;
  &lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt;
  jQuery(function() {
    $("a").live("click", function(e) {
      alert("a");
      e.preventDefault();
    });
    $("a").live("click", function(e) {
      alert("b");
      e.preventDefault();
    });
  });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href="http://blog.fxposter.org/"&gt;Блог FX-а&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>И самое главное (барабанная дробь!) - при использовании bind() для навешивания обработчиков preventDefault() тоже можно использовать!</p>
<p>Наткнулись мы на эту &#8220;фичу&#8221;, когда у нас почему-то перестали вызываться <strong>некоторые</strong> обработчики</p>
<p>Напоследок, замечу еще одно - элемент, на который навешено хотя бы один обработчик события через bind() с &#8220;правильно работающим return false&#8221;, никогда не будет вызывать никакие live()-события. ;)</p>
<p>Так что будьте бдительны и не забывайте об особенностях обработки событий в JS. Удачи.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/06/16/jquery-live-method/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>MongoDB и MongoMapper &#8211; небольшой отчет об использовании</title>
		<link>http://blog.fxposter.org/2010/05/10/mongodb-and-mongomapper-small-usage-report/</link>
		<comments>http://blog.fxposter.org/2010/05/10/mongodb-and-mongomapper-small-usage-report/#comments</comments>
		<pubDate>Mon, 10 May 2010 20:19:20 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[MongoMapper]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby-On-Rails]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=775</guid>
		<description><![CDATA[Недавно писал проект на Rails 2.3 + MongoDB + MongoMapper. Не могу сказать, что все было хорошо - для того, чтобы существующие плагины для рельсов заработали с MongoMapper-ом пришлось немного повозиться, но в итоге все закончилось хорошо. :) А мой сегодняшний рассказ пойдет о некоторых особенностях MongoDB и MongoMapper-а, с которыми вы, скорее всего столкнетесь, [...]]]></description>
			<content:encoded><![CDATA[<p>Недавно писал проект на <a href="http://rubyonrails.org/">Rails 2.3</a> + <a href="http://www.mongodb.org/">MongoDB</a> + <a href="http://github.com/jnunemaker/mongomapper">MongoMapper</a>. Не могу сказать, что все было хорошо - для того, чтобы существующие плагины для рельсов заработали с MongoMapper-ом пришлось немного повозиться, но в итоге все закончилось хорошо. :)</p>
<p>А мой сегодняшний рассказ пойдет о некоторых особенностях MongoDB и MongoMapper-а, с которыми вы, скорее всего столкнетесь, если будете использовать эти библиотеки.</p>
<p>Для начала поговорим немного о MongoDB. Что это такое?</p>
<blockquote cite="http://ru.wikipedia.org/wiki/MongoDB"><p>MongoDB — документо-ориентированная система управления базами данных (СУБД) с открытым исходным кодом, не требующая описания схемы таблиц. Написана на языке C++. СУБД управляет наборами JSON-подобных документов, хранимых в двоичном виде в формате BSON.</p></blockquote>
<p>Если попробовать вкратце охарактеризовать эту базу данных, то получится что-то вроде этого: аналог реляционной СУБД без join-ов и транзакций, зато с поддержкой структур данных (массивов, хешей).</p>
<p>MongoMapper - это &#8220;<a href="http://ru.wikipedia.org/wiki/ORM">ORM</a>&#8221; для MongoDB, написанный на руби. &#8220;ORM&#8221; в кавычках потому что сложно себе представить ORM для нереляционной базы данных. Я бы скорее назвал это высокоуровневой оберткой над API, которое предоставляет MongoDB, с поддержкой ассоциаций между записями и много чем еще.</p>
<p>Теперь, собственно, о &#8220;особенностях&#8221; MongoDB и MongoMapper-а.</p>
<h3>Вложенные документы</h3>
<p>Вложенные документы в понятии MongoMapper-а - это когда одни обьекты хранят внутри себя другие. Для примера, возьмем следующую модель:</p>
<pre><code class="ruby">class User
  include MongoMapper::Document

  key :login
  key :password
  key :salt

  many :posts
  many :addresses
end

class Post
  include MongoMapper::Document
  key :title, String
  key :body, String
  timestamps!
end

class Address
  include MongoMapper::EmbeddedDocument
  key :type, String
  key :country_id, ObjectId
  key :city_id, ObjectId
  key :city_address, String
end</code></pre>
<p>Чтобы понимать, что тут происходит нужно, во-первых знать <a href="http://www.ruby-lang.org/">Ruby</a> :) и во вторых - прочесть <a href="http://railstips.org/blog/archives/2009/06/27/mongomapper-the-rad-mongo-wrapper/">пост</a> John Nunemaker (даже не знаю, как правильно перевести :)) о MongoMapper-е. Вот <a href="http://railstips.org/2009/12/18/why-i-think-mongo-is-to-databases-what-rails-was-to-frameworks/">еще один</a>, кстати, тоже интересный.</p>
<p>Таким образом имеем модель пользователя, которая хранить набор постов, написанных этим пользователем и набор адресов пользователя (домашний, рабочий, etc).</p>
<p>Особенности работы со встроенными документами легче показать на примере:</p>
<pre><code class="ruby">user = User.first
user.posts</code></pre>
<p>Последняя комманда вернет &#8220;scope&#8221;/&#8221;relation&#8221;, а не просто массив элементов (люди, знакомые с named_scope в ActiveRecord версии &lt; 3 поймут).<br />
Соответственно, можно дродолжить эту комманду, например, так:</p>
<pre><code class="ruby">user.posts.all(:conditions =&gt; { :created_at =&gt; { "$gt" =&gt; (Date.today - 10.days) } })</code></pre>
<p>В то время как</p>
<pre><code class="ruby">user.addresses</code></pre>
<p>вернет массив и всю дополнительную фильтрацию прийдется производить с помощью Ruby.</p>
<h3>Манипуляции со вложенными документами</h3>
<p>У EmbeddedDocument нет понятия &#8220;id&#8221;, т.е. отличать обьекты Address один от другого можно только по их индексу в массиве user.addresses либо вводя &#8220;свои&#8221; идентификаторы. Но даже в этом случае выбирать соответствующий обьект прийдется &#8220;вручную&#8221;:</p>
<pre><code class="ruby">user.addresses.detect { |address| address.identifier == params[:address_identifier] }</code></pre>
<p class="offtopic">PS. Для тех, кто в танке: detect - это аналог select { |address| &#8230; }.first.</p>
<p>Соответственно - вложенные обьекты легко добавлять, выбирать всю связь полностью, но с ними становится &#8220;сложно&#8221; работать, как с отдельными обьектами. В частности - неудобно обновлять из-за проблем с выборкой отдельного элемента и неудобно удалять.</p>
<p>С удалением вообще интересная история. Удалить обьект имея только ссылку на него - нельзя, нужна еще и ссылка на массив, в котором он хранится:</p>
<pre><code class="ruby">user.addresses.first.delete/destroy</code></pre>
<p>не работает, т.к. таких методов у вложенных обьектов нет. Нужно делать так:</p>
<pre><code class="ruby">user.addresses.delete_at(address_index)</code></pre>
<p>если вы знаете индекс в массиве адресов, либо</p>
<pre><code class="ruby">user.addresses.delete_if { |address| address.identifier == address_identifier }</code></pre>
<p>если знаете идентификатор или удаляете по какому-либо другому полю.</p>
<p>Несложно, но проблемы на первых порах с этим бывают.</p>
<h3>&#8220;идентификаторы&#8221; обьектов MongoDB</h3>
<p>Каждому обьекту в бд MongoDB присваивает свой идентификатор. Как он по умолчанию строится можно посмотреть <a href="http://www.mongodb.org/display/DOCS/Object+IDs">здесь</a>. Обычно эти идентификаторы совсем не мешают, но иногда хочется просто засунуть вместо них какие-нибудь данные.</p>
<p>Например, вместо такой модели:</p>
<pre><code class="ruby">class Tag
  include MongoMapper::Document
  key :name, String
end</code></pre>
<p>иметь такую</p>
<pre><code class="ruby">class Tag
  include MongoMapper::Document
  # id-шник явно никогда не прописывается
end</code></pre>
<p>И создавать обьект так:</p>
<pre><code class="ruby">Tag.create(:_id =&gt; "ruby on rails")</code></pre>
<p>MongoDB это позволяет делать. Более того - драйвер Ruby для MongoDB это тоже может делать. Проблема в том, что это не умеет делать MongoMapper. Совершенно. Как обойти эту проблему я на данный момент не знаю (я в итоге сделал модель первого типа и забил), есди кто знает решение - напишите, будет интересно.</p>
<p>И напоследок поговорим о</p>
<h3>Has And Belongs To Many в MongoDB</h3>
<p>&#8230; или <a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#M001836">habtm</a>, знакомый многим по ActiveRecord.</p>
<p>Приведу пример из моего проекта: есть домены, есть их модераторы, связть many-to-many. Для каждого домена хочется видеть список модераторов и для каждого модератора хочется видеть список доменов, которые он модерирует.</p>
<p>Честно говоря, задача поставила меня в тупик. Т.е. как все мы решаем эти задачи с помощью RDBMS? Правильно - связующей таблицей. Так же можно было поступить и здесь, но&#8230; Как-то это было некрасиво, на мой взгляд, использовать этот подход вв документоориентированной базе данных.</p>
<p>Первое решение, которое мне пришло в голову - хранить массив id-шников доменов для каждого пользователя и хранить массив id-шников пользователей для каждого домена и синхронизировать их.</p>
<p>Последние два слова очень смущали - синхронизация вносила излишнюю сложность. Т.е. реализовать-то её можно, но очень не хотелось.</p>
<p>Собственно, обратился за помощью к знакомым и вышел на одного человека (ник - Necromant, сайта его я не знаю :) ), который помог решить мне эту проблему.</p>
<p>Итак, решение - хранить только один список id-шников (или в юзерах или в доменах) и сделать по нему индекс, соответственно, вывод как доменов по юзеру так и юзеров по домену будет достаточно быстрый.</p>
<p>Я хранил массив юзеров для домена, т.к. если бы я сделал иначе, то при удалении домена пришлось бы пройтись по всем юзерам и удалить все связи на домен, а в выбранном варианте этого делать не нужно (а удаление юзеров - это пока что вообще не существующее событие для моего проекта):</p>
<pre><code class="ruby">class Domain
  include MongoMapper::Document
  # ...
  key :moderator_ids, Array, :index =&gt; true
  def moderators
    User.find moderator_ids
  end
end

class User
  include MongoMapper::Document
  # ...
  def moderator_of?(domain)
    domain.moderator_ids.include? id.to_s
  end

  def moderated_domains
    Domain.all :moderator_ids =&gt; id.to_s
  end
end</code></pre>
<p>Еще хочу рассказать о том, как подружить MongoMapper и <a href="http://github.com/thoughtbot/clearance">Clearance</a>, но пост вроде и так не маленький получился, так что ждите еще один пост о MongoMapper-е в ближайшие дни.</p>
<p><em><strong>PS</strong>. Совсем писать разучился&#8230; :(</em></p>
<p><em><strong>PPS</strong>. Если вам понравился этот пост, <a href="http://habrahabr.ru/blogs/ruby/93212/">проголосуйте</a> за него на Habrahabr-е. :)<br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/05/10/mongodb-and-mongomapper-small-usage-report/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Ressurection</title>
		<link>http://blog.fxposter.org/2010/05/02/ressurection/</link>
		<comments>http://blog.fxposter.org/2010/05/02/ressurection/#comments</comments>
		<pubDate>Sun, 02 May 2010 00:04:15 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[macbook]]></category>
		<category><![CDATA[macosx]]></category>
		<category><![CDATA[objective-c]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=766</guid>
		<description><![CDATA[Настало время возродить этот блог. За более чем полугодие на нем не появилось ни одной статьи и я наконец-то намерен прекратить этот &#8220;застой&#8221;. Да, по сравнению с временами, которые были раньше у меня стало существенно меньше времени, чтобы писать что-то большое и серьезное - работа, университет (если быть точнее - то написание диплома) и еще [...]]]></description>
			<content:encoded><![CDATA[<p>Настало время возродить этот блог. За более чем полугодие на нем не появилось ни одной статьи и я наконец-то намерен прекратить этот &#8220;застой&#8221;. Да, по сравнению с временами, которые были раньше у меня стало существенно меньше времени, чтобы писать что-то большое и серьезное - работа, университет (если быть точнее - то написание диплома) и еще один &#8220;секретный сайд проект&#8221; о котором, возможно, я когда-нибудь всем расскажу.</p>
<p>Начну с глобальных изменений, которые произошли за последнее время в моей жизни и которые однозначно коснутся этого блога.</p>
<p>Ну, во-первых, я теперь не пишу на PHP. Вообще не пишу. И не очень сильно слежу за последними веяниями моды, связанными с этим языком. Да, я все равно иногда появляюсь в группе симфонистов (кому нужен доступ туда - пишите, там новичков любят и на многие нубские вопросы отвечают :) ). Да, я иногда посматриваю на фреймворки, которые сейчас являются популярными в сфере PHP - всякие Yii, ZF, etc. Посматриваю исключительно для того, чтобы быть в курсе происходящего. Учить их и писать на них в общем-то не очень хочется.</p>
<p>На что я променял PHP? Естественно на <a href="http://www.ruby-lang.org/">Ruby</a>. Я не восхищаюсь этим языком, не превозношу его над остальными, просто на работе я пишу на нем (кстати, я работаю над стартапом для бизнесов - <a href="http://waysgo.com/">WaysGo</a>, запуск будет, я надеюсь, очень скоро) и ни на чем другом желания писать особо не возникает - с точки зрения веб-разработки Ruby меня полностью устраивает. Этот язык удобен и достаточно экспрессивен. А <a href="http://rubyonrails.org/">Ruby On Rails</a> - отличное средство для тех, кто хочет писать веб-приложения. Ну, в общем, вы меня поняли. ;)</p>
<p>Кстати говоря, я немного соврал насчет того, что я пишу на Ruby на работе. С начала этой недели я пишу iPhone-приложение на <a href="http://ru.wikipedia.org/wiki/Objective-C">Objective-C</a> и, в связи с этим, шустренько осваиваю Mac, Xcode, сам Objective-C и всякую прочую фигню, которая нужна для разработки под iPhone. Определенного мнения по поводу мака я пока сказать не могу, а вот Objective-C с первого подхода отличается похожестью на руби с точки зрения вызовов методов у объектов и открытых классов, но в то же время отличается несколько некрасивым синтаксисом (квадратные скобки, рррррр). С другой стороны, к синтаксису Ruby у меня тоже изначально было плохое отношение. Это отношение, кстати, не изменилось - я по прежнему считаю, что Ruby - непонятный язык для новичка, и если код на, например, Python можно просто читать, то для того, чтобы почитать код на Ruby придется сначала посмотреть туториалы, или что-то в этом роде, потому что синтаксис кроме выразительности отличается еще и неочевидностью. После пары дней работы с Ruby проблемы отпадают сами собой, так что этот аспект меня уже не очень беспокоит. Собственно, я надеюсь, что рано или поздно я перестану замечать синтаксис Objective-C и буду просто писать код, который делает что мне нужно.</p>
<p>Вот, собственно, и все на сегодня. Вроде ничего не забыл. До скорого! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2010/05/02/ressurection/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>David Heinemeier Hansson at Startup School 08</title>
		<link>http://blog.fxposter.org/2009/09/16/david-heinemeier-hansson-at-startup-school-08/</link>
		<comments>http://blog.fxposter.org/2009/09/16/david-heinemeier-hansson-at-startup-school-08/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 20:34:17 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[Moneymaking]]></category>
		<category><![CDATA[Startups]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=741</guid>
		<description><![CDATA[Видео от создателя Ruby On Rails и одного из первых сотрудников 37 Signals о том, что нужно делать, чтобы зарабатывать деньги в интернете (&#8221;The secret of making money online&#8221;). Видео я смотрел давно уже, но без слайдов. После того, как мне наш проджект менеджер прислал ссылку на это же видео, решил найти вариант со слайдами. [...]]]></description>
			<content:encoded><![CDATA[<p>Видео от создателя Ruby On Rails и одного из первых сотрудников 37 Signals о том, что нужно делать, чтобы зарабатывать деньги в интернете (&#8221;The secret of making money online&#8221;). Видео я смотрел давно уже, но без слайдов. После того, как мне наш проджект менеджер прислал ссылку на это же видео, решил найти вариант со слайдами. <a href="http://www.omnisio.com/startupschool08/david-heinemeier-hansson-at-startup-school-08">Смотрим</a>.</p>
<p><strong><em>PS</em></strong>. DHH рассказывает, казалось бы, об очевидных вещах. Однако отнюдь не всем эти вещи приходят в голову без &#8220;толчка&#8221; со стороны.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/09/16/david-heinemeier-hansson-at-startup-school-08/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby And Rails Barcamp</title>
		<link>http://blog.fxposter.org/2009/09/04/ruby-and-rails-barcamp/</link>
		<comments>http://blog.fxposter.org/2009/09/04/ruby-and-rails-barcamp/#comments</comments>
		<pubDate>Thu, 03 Sep 2009 21:24:44 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[BarCamp]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby-On-Rails]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=721</guid>
		<description><![CDATA[26-го сентября, в субботу, в Киеве будет проведен BarCamp на тему языка Ruby и фреймворка Ruby On Rails. Место проведения зависит от количества желающих посетить данное мероприятие и на данный момент уточняется. Если не произойдет ничего особенного - я туда скорее всего поеду. Буду рад увидеть там читателей своего блога. ;) Заходим, смотрим, регистрируемся.]]></description>
			<content:encoded><![CDATA[<p>26-го сентября, в субботу, в Киеве будет проведен <a href="http://ru.wikipedia.org/wiki/BarCamp">BarCamp</a> на тему языка Ruby и фреймворка Ruby On Rails. Место проведения зависит от количества желающих посетить данное мероприятие и на данный момент уточняется. Если не произойдет ничего особенного - я туда скорее всего поеду. Буду рад увидеть там читателей своего блога. ;)</p>
<p><a href="http://rubylang.org.ua/">Заходим</a>, смотрим, регистрируемся.<a href="http://rubylang.org.ua/"></a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/09/04/ruby-and-rails-barcamp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ Developer Needed</title>
		<link>http://blog.fxposter.org/2009/06/10/cpp-developer-needed/</link>
		<comments>http://blog.fxposter.org/2009/06/10/cpp-developer-needed/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 21:05:49 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Работа]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=714</guid>
		<description><![CDATA[Нужен хороший C++-программист для интересного проекта (создание поискового движка для веб-сайта). Требования: Обязательны хорошие знания в следующих областях: C++ Linux Pthreads Sockets Алгоритмы (в частности графы) Желательно знать: Boost (Thread, Asio, Graph, etc) Ruby/Rails MySQL/PostgreSQL/BerkeleyDB Паттерны проектирования Работать нужно в офисе (как оказалось, для некоторых это критично). Офис находится в Днепропетровске, в центре города. Ответы [...]]]></description>
			<content:encoded><![CDATA[<p>Нужен хороший C++-программист для интересного проекта (создание поискового движка для веб-сайта).</p>
<p>Требования:</p>
<ul>
<li>Обязательны хорошие знания в следующих областях:
<ul>
<li>C++</li>
<li>Linux</li>
<li>Pthreads</li>
<li>Sockets</li>
<li>Алгоритмы (в частности графы)</li>
</ul>
</li>
<li>Желательно знать:
<ul>
<li>Boost (Thread, Asio, Graph, etc)</li>
<li>Ruby/Rails</li>
<li>MySQL/PostgreSQL/BerkeleyDB</li>
<li>Паттерны проектирования</li>
</ul>
</li>
</ul>
<p>Работать нужно в офисе (как оказалось, для некоторых это критично). Офис находится в Днепропетровске, в центре города.</p>
<p>Ответы пишите сюда, в Skype (fxposter), Jabber (fxposter@gmail.com) или ICQ (625585).</p>
<p><em><strong>PS</strong>. Для того, чтобы не появлялись вопросы типа &#8220;а причем тут рельсы?&#8221; - сам проект пишется на Ruby/Rails, часть поискового движка - на C++.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/06/10/cpp-developer-needed/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Drop ACID and think about data</title>
		<link>http://blog.fxposter.org/2009/05/08/drop-acid-and-think-about-data/</link>
		<comments>http://blog.fxposter.org/2009/05/08/drop-acid-and-think-about-data/#comments</comments>
		<pubDate>Fri, 08 May 2009 20:46:35 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Работа]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[highload]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=705</guid>
		<description><![CDATA[Чрезвычайно интересное видео выступления Боба Ипполито на PyCon 2009, в котором он рассказывает о современных системах хранения данных. Очень заинтересовала Cassandra и Column-Oriented Databases. Очень рекомендую посмотреть всем, кто занимается построением высокопроизводительных систем, которые оперируют большим количеством данных. У меня как раз такой случай, так что пойду изучать Cassandra, LucidDB и C-Store. И самое приятное [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://us.pycon.org/2009/conference/schedule/event/64/">Чрезвычайно интересное видео</a> выступления Боба Ипполито на PyCon 2009, в котором он рассказывает о современных системах хранения данных. Очень заинтересовала Cassandra и Column-Oriented Databases. Очень рекомендую посмотреть всем, кто занимается построением высокопроизводительных систем, которые оперируют большим количеством данных. У меня как раз такой случай, так что пойду изучать Cassandra, LucidDB и C-Store.</p>
<p>И самое приятное - всех с праздничком, с Днем Победы!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/05/08/drop-acid-and-think-about-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>В Крым на денек</title>
		<link>http://blog.fxposter.org/2009/05/01/going-to-crimea-for-one-day/</link>
		<comments>http://blog.fxposter.org/2009/05/01/going-to-crimea-for-one-day/#comments</comments>
		<pubDate>Fri, 01 May 2009 10:37:52 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Работа]]></category>
		<category><![CDATA[Разное]]></category>
		<category><![CDATA[Отдых]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=698</guid>
		<description><![CDATA[Давно не писал здесь ничего. В какой-то степени это связано с тем, что в последнее время навалилось много дел - как по учебе, так и по работе (кстати, теперь я работаю в Dimalex). С другой стороны - на той же работе я сейчас занимаюсь не написанием кода, а разработкой требований, написанием ТЗ, проектированием архитектуры (Kpumuk, [...]]]></description>
			<content:encoded><![CDATA[<p>Давно не писал здесь ничего. В какой-то степени это связано с тем, что в последнее время навалилось много дел - как по учебе, так и по работе (кстати, теперь я работаю в <a href="http://dimalex.eu/">Dimalex</a>). С другой стороны - на той же работе я сейчас занимаюсь не написанием кода, а разработкой требований, написанием ТЗ, проектированием архитектуры (<a href="http://kpumuk.info/">Kpumuk</a>, <a href="http://abrdev.com/">aleks raiden</a> - вам отдельное спасибо за подсказки и ответы на мои глупые вопросы :)). Так что&#8230; Интересных постов о том, о чем я писал раньше - PHP, Symfony, ZF, etc. Тут, скорее всего до лета не будет. Зато, возможно, будет что-то о Hadoop и параллельной обработке большого количества данных&#8230; Не знаю еще. Мне многому предстоит научиться, т.к. опыта разработки высокопроизводительных приложений я не имею, но как раз этому я очень рад.</p>
<p>Но именно сейчас это не главное, т.к. сегодня вечером (часиков, эдак, через 8) я уже буду на поезде, который повезет меня с моей девушкой в Крым. В планах - посетить <a href="http://www.gnbs.simple-true.org.ua/rus/">ботанический сад</a>, посмотреть на море и просто отдохнуть душой и телом, а вечером - на поезд обратно.</p>
<p>Всех с праздничком! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/05/01/going-to-crimea-for-one-day/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Теперь я безработный</title>
		<link>http://blog.fxposter.org/2009/02/06/unemployed/</link>
		<comments>http://blog.fxposter.org/2009/02/06/unemployed/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 16:00:51 +0000</pubDate>
		<dc:creator>fxposter</dc:creator>
				<category><![CDATA[Работа]]></category>

		<guid isPermaLink="false">http://blog.fxposter.org/?p=659</guid>
		<description><![CDATA[Собственно, сабж. Не спрашивайте - почему и из-за чего. Сам виноват. :) Но ничего! Что не делается - то к лучшему. Теперь у меня будет больше свободного времени, которое я с удовольствием потрачу на себя. В планах: Все-таки прочесть &#8220;Рефакторинг&#8221; Фаулера и &#8220;Code Complete&#8221; МакКоннелла (хотя некто говорит, что он очень нудно пишет) Поближе познакомиться [...]]]></description>
			<content:encoded><![CDATA[<p>Собственно, сабж.</p>
<p>Не спрашивайте - почему и из-за чего. Сам виноват. :)</p>
<p>Но ничего! Что не делается - то к лучшему. Теперь у меня будет больше свободного времени, которое я с удовольствием потрачу на себя. В планах:</p>
<ul>
<li>Все-таки прочесть &#8220;Рефакторинг&#8221; Фаулера и &#8220;Code Complete&#8221; МакКоннелла (хотя некто говорит, что он очень нудно пишет)</li>
<li>Поближе познакомиться с Ruby/Rails</li>
<li>Прочесть что-нибудь по .NET, ASP.NET и поюзать ASP.NET MVC</li>
</ul>
<p>Если у вас есть какие-то пожелания насчет блога (например, хотите увидеть статью по какой-нибудь тематике) - пишите в комментах!</p>
<p><em><strong>PS</strong>. Хотя, надеюсь, в скором времени </em><em>для меня</em><em> найдется </em><em>работа</em><em>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.fxposter.org/2009/02/06/unemployed/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
