<?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/"
	>

<channel>
	<title>ThinkRobot &#187; doctrine</title>
	<atom:link href="http://think-robot.com/tag/doctrine/feed/" rel="self" type="application/rss+xml" />
	<link>http://think-robot.com</link>
	<description>Design &#38; Development Blog</description>
	<pubDate>Sun, 05 Sep 2010 23:09:50 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multiple changes and a delete on same object in doctrine</title>
		<link>http://think-robot.com/2010/03/multiple-changes-and-a-delete-on-same-object-in-doctrine/</link>
		<comments>http://think-robot.com/2010/03/multiple-changes-and-a-delete-on-same-object-in-doctrine/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 20:58:13 +0000</pubDate>
		<dc:creator>Joanna</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[doctrine]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[solution]]></category>

		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://think-robot.com/?p=219</guid>
		<description><![CDATA[If you want to make several different changes to a doctrine record object you might find yourself slightly puzzled when it comes to deleting related objects.
$user['Address']->delete();
$user['Address']->state(Doctrine_Record::STATE_LOCKED);
(...)
$user->save();
It seems that unless you set the state the save later on still sees an initialized (though empty!) relation.
Related Articles:Hitch. Object-oriented event handlers with jQueryDoctrine Many To Many With Extra [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to make several different changes to a doctrine record object you might find yourself slightly puzzled when it comes to deleting related objects.</p>
<pre><code><code>$user['Address']->delete();
$user['Address']->state(Doctrine_Record::STATE_LOCKED);
(...)
$user->save();</code></code></pre>
<p>It seems that unless you set the state the save later on still sees an initialized (though empty!) relation.</p>
<div id="crp_related"><h2>Related Articles:</h2><ul><li><a href="http://think-robot.com/2009/06/hitch-object-oriented-event-handlers-with-jquery/" rel="bookmark">Hitch. Object-oriented event handlers with jQuery</a></li><li><a href="http://think-robot.com/2009/05/doctrine-many-to-many-with-extra-fields/" rel="bookmark">Doctrine Many To Many With Extra Fields</a></li><li><a href="http://think-robot.com/2008/08/server-error-500-htaccess-require-valid-user/" rel="bookmark">Server Error 500 - htaccess require valid-user</a></li><li><a href="http://think-robot.com/2008/06/atmedia-london-2008/" rel="bookmark">@media - London, 2008</a></li><li><a href="http://think-robot.com/2008/08/opensuse-11-on-lenovo-thinkpad-x61-tablet-pc/" rel="bookmark">openSUSE 11 on Lenovo Thinkpad X61 (tablet pc)</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://think-robot.com/2010/03/multiple-changes-and-a-delete-on-same-object-in-doctrine/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Doctrine Many To Many With Extra Fields</title>
		<link>http://think-robot.com/2009/05/doctrine-many-to-many-with-extra-fields/</link>
		<comments>http://think-robot.com/2009/05/doctrine-many-to-many-with-extra-fields/#comments</comments>
		<pubDate>Sat, 09 May 2009 10:25:13 +0000</pubDate>
		<dc:creator>Joanna</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[database]]></category>

		<category><![CDATA[doctrine]]></category>

		<category><![CDATA[many to many]]></category>

		<category><![CDATA[php]]></category>

		<category><![CDATA[YAML]]></category>

		<guid isPermaLink="false">http://think-robot.com/?p=180</guid>
		<description><![CDATA[Recently I have started using Doctrine with Zend Framework. Most of the time it is great, but sometimes I get stuck on this or that issue. Most of my problems so far have been connected with the Many to Many relationship. Here are a few tips I learned the hard way.
Automatic relationship detection
When setting up [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I have started using Doctrine with Zend Framework. Most of the time it is great, but sometimes I get stuck on this or that issue. Most of my problems so far have been connected with the Many to Many relationship. Here are a few tips I learned the hard way.<span id="more-180"></span></p>
<h2>Automatic relationship detection</h2>
<p>When setting up a YAML file with your database schema you can start it with the handy declaration:</p>
<pre><code><code>---
detect_relations: true</code></code></pre>
<p>It does the One to Many relationship for you nicely, however the Many to Many ones did not work out of the box and required manual BaseModel tweaking. Take for example my <strong>Tag</strong>, <strong>Website</strong>, and <strong>WebsiteTag</strong> classes.</p>
<h3>BaseTag:</h3>
<pre><code><code>abstract class BaseTag extends Doctrine_Record {

  public function setTableDefinition() {
    $this-&gt;setTableName('ts_tags');
    $this-&gt;hasColumn('name', 'string', 128, array('type' =&gt; 'string', 'length' =&gt; '128'));
    $this-&gt;hasColumn('is_category as isCategory', 'integer', 1, array('type' =&gt; 'integer', 'length' =&gt; '1'));
    $this-&gt;hasColumn('page_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8));
    $this-&gt;hasColumn('ordering', 'integer', 5, array('type' =&gt; 'integer', 'length' =&gt; '5'));
  }

  public function setUp() {
    $this-&gt;hasOne('Page', array('local' =&gt; 'page_id',
                                              'foreign' =&gt; 'id'));
<strong>
    $this-&gt;hasMany('Website as Websites', array('local' =&gt; 'tag_id',
                                                                     'foreign' =&gt; 'website_id',
                                                                     'refClass' =&gt; 'WebsiteTag'));</strong>

    $i18n0 = new Doctrine_Template_I18n(array('fields' =&gt; array(0 =&gt; 'name')));
    $this-&gt;actAs($i18n0);
  }
}</code></code></pre>
<h3>BaseWebsite:</h3>
<pre><code><code>abstract class BaseWebsite extends Doctrine_Record{
  public function setTableDefinition() {
    $this-&gt;setTableName('ts_websites');
    $this-&gt;hasColumn('page_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8));
    $this-&gt;hasColumn('title', 'string', 128, array('type' =&gt; 'string', 'length' =&gt; '128'));
    $this-&gt;hasColumn('client', 'string', 128, array('type' =&gt; 'string', 'length' =&gt; '128'));
    $this-&gt;hasColumn('link', 'string', 255, array('type' =&gt; 'string', 'length' =&gt; '255'));
    $this-&gt;hasColumn('intro', 'string', null, array('type' =&gt; 'string'));
    $this-&gt;hasColumn('content', 'string', null, array('type' =&gt; 'string'));
    $this-&gt;hasColumn('published', 'timestamp', null, array('type' =&gt; 'timestamp'));
    $this-&gt;hasColumn('is_home as isHome', 'integer', 1, array('type' =&gt; 'integer', 'length' =&gt; '1'));
  }

  public function setUp() {
    $this-&gt;hasOne('Page', array('local' =&gt; 'page_id',
                                              'foreign' =&gt; 'id'));

    <strong>$this-&gt;hasMany('Tag as Tags', array('local' =&gt; 'website_id',
                                                          'foreign' =&gt; 'tag_id',
                                                          'refClass' =&gt; 'WebsiteTag'));</strong>

    $this-&gt;hasMany('Media', array('local' =&gt; 'website_id',
                                                 'foreign' =&gt; 'media_id',
                                                 'refClass' =&gt; 'WebsiteMedia'));

    $i18n0 = new Doctrine_Template_I18n(array('fields' =&gt; array(0 =&gt; 'intro', 1 =&gt; 'content', 2 =&gt; 'title')));
    $this-&gt;actAs($i18n0);
  }
}
</code></code></pre>
<h3>BaseWebsiteTag:</h3>
<pre><code><code>abstract class BaseWebsiteTag extends Doctrine_Record {

  public function setTableDefinition() {
    $this-&gt;setTableName('ts_website_has_tags');
    $this-&gt;hasColumn('tag_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8, <strong>'primary' =&gt; true )</strong>);
    $this-&gt;hasColumn('website_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8,<strong> 'primary' =&gt; true</strong>));
  }

  public function setUp() {
  }
}
</code></code></pre>
<p>The highlighted portions of code needed to be added. You can actually define these manually in the YAML file, the catch is that I was expecting it to happen magically with the auto relationship setting.</p>
<h2>Many to Many with extra fields</h2>
<p>Another little issue that Doctrine has is when you try to retrieve records. It in a way skips the joining table and retrieves a collection of the final items. In most cases this is exactly what you might need. However for my Media I decided to keep the ordering in the joining table - WebsiteMedia.</p>
<pre><code><code>$q = Doctrine_Query::create()
  -&gt;from('Website w')
  -&gt;joinLeft('w.Media');</code></code></pre>
<p>If you simply proceed with the above you only get Media objects without the ordering.</p>
<h3>BaseWebsiteMedia:</h3>
<pre><code><code>abstract class BaseWebsiteMedia extends Doctrine_Record {

    public function setTableDefinition() {
        $this-&gt;setTableName('ts_website_has_media');
        $this-&gt;hasColumn('website_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8, 'primary' =&gt; true));
        $this-&gt;hasColumn('media_id', 'integer', 8, array('type' =&gt; 'integer', 'length' =&gt; 8, 'primary' =&gt; true));
        $this-&gt;hasColumn('caption', 'string', 255, array('type' =&gt; 'string', 'length' =&gt; '255'));
        $this-&gt;hasColumn('is_main as isMain', 'integer', 1, array('type' =&gt; 'integer', 'length' =&gt; '1'));
        $this-&gt;hasColumn('ordering', 'integer', 4, array('type' =&gt; 'integer', 'length' =&gt; '4'));
    }

    public function setUp() {
        <strong>$this-&gt;hasOne('Website', array('local' =&gt; 'website_id',
                                       'foreign' =&gt; 'id'));

        $this-&gt;hasOne('Media', array('local' =&gt; 'media_id',
                                     'foreign' =&gt; 'id'));</strong>

        $i18n0 = new Doctrine_Template_I18n(array('fields' =&gt; array(0 =&gt; 'caption')));
        $this-&gt;actAs($i18n0);
    }
}</code></code></pre>
<p>If you do not have the additional One to Many relations declared already you should add them now. With the modified model now you can get the records like so:</p>
<pre><code><code>$q = Doctrine_Query::create()
  ->from('Website w')
  ->leftJoin('w.WebsiteMedia wm')
    ->leftJoin('wm.Media m');
</code></code></pre>
<p>This gives you a collection of WebsiteMedia records each containing the actual Media item.</p>
<div id="crp_related"><h2>Related Articles:</h2><ul><li><a href="http://think-robot.com/2009/04/zend_db_select-multiple-table-joins-explained/" rel="bookmark">Zend_Db_Select multiple table joins explained</a></li><li><a href="http://think-robot.com/2009/02/zend-framework-decorators-labels-and-checkboxes/" rel="bookmark">Zend Framework Decorators - Labels and Checkboxes</a></li><li><a href="http://think-robot.com/2009/07/autloading-modular-forms-models-in-zend-framework-18/" rel="bookmark">Autloading modular forms & models in Zend Framework 1.8</a></li><li><a href="http://think-robot.com/2008/12/using-zend_mail-and-google-smtp-to-send-emails/" rel="bookmark">Using Zend_Mail and Google SMTP to send emails</a></li><li><a href="http://think-robot.com/2008/11/nested-sortable-using-jtree-clickable-links/" rel="bookmark">Nested sortable using jTree - clickable links</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://think-robot.com/2009/05/doctrine-many-to-many-with-extra-fields/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
