Welcome Guest, Not a member yet? Register   Sign In
[Deprecated] DMZ 1.5.3 (DataMapper OverZealous Edition)

[eluser]KSiimson[/eluser]
I have a list of countries, and a list of objects. I also have an array of countries to be associated with the object. If I use just save(), then the relationships will be added. The old relationship will stay intact, which is not what I want. What would be the best approach to delete all the relationships associated with an object? It seems to me that I would need a list of countries that I want to remove, but I am not sure it is necessary?

[eluser]OverZealous[/eluser]
[quote author="KSiimson" date="1254780618"]What would be the best approach to delete all the relationships associated with an object?[/quote]

There are several ways. You can first unrelated all of them, then save the new ones (fine for small numbers of related items):
Code:
$countries = $object->country->select('id')->get();
$object->delete($countries->all);

// already looked up $new_countries elsewhere
$object->save($new_countries);

You could also write some code to loop through the list of countries, removing the old ones, and then saving the new ones (better if you have more than 5 or so related items):
Code:
$new_country_ids = array(...); // array of IDs

// loop through existing relationships, and remove old ones
$countries = $object->country->select('id')->get();
foreach($countries->all as $c) {
    $idx = array_search($c->id, $new_country_ids);
    if($idx === FALSE) {
        $object->delete($c);
    } else {
        // optional, but saves a few queries
        unset($new_country_ids[$ids]);
    }
}

// now look up the new countries, and save them
$new_countries = new Country();
$new_countries->where_in('id', $new_country_ids)->get();
$object->save($new_countries->all);

// if you want to use countries now, you'll need to re-look them up:
$object->country->get();

In the end, DMZ has to remove each non-related object, and then add each new object. In the background, DMZ does some cleanup work.

[eluser]Jeffrey Lasut[/eluser]
@Jinkusu
After playing with the code this made it work for me in DMZ:

Code:
class Product extends Datamapper
  {
    var $table = 'products'; //need to specify the table, else db error message table books/cars doesn't exist

    function __construct($id = null) {
      parent::__construct($id);
    }
  }

  class Book extends Product
  {
    function __construct($id = null) {
      parent::__construct($id);
    }

    function get_title()
    {
      return $this->title;
    }
  }

  class Car extends Product
  {
    function __construct($id = null) {
      parent::__construct($id);
    }

    function get_title()
    {
      return $this->title;
    }
  }

[eluser]OverZealous[/eluser]
I'll be interested in hearing how this works for you.

I've had trouble in the past using inheritance (I've got one inherited class in my app, and it causes headaches), which is why I always recommend against it. If you get it working well (including querying, saving, and deleting), and wouldn't mind, I'd love to see some examples and possibly include them in the documentation at a later date.

[eluser]Jeffrey Lasut[/eluser]
@OverZealous
No problem, I'm planning to test the various options in DMZ.
When I'm done I'll post the results or questions :-)

[eluser]Jeffrey Lasut[/eluser]
@OverZealous

Just like I promised a working example, but I didn't try all the DMZ features.
So there is still some testing to do.

Please send me any feedback.

Jeffrey

edit:
- some code cleaning
- added db test records

[eluser]Jeffrey Lasut[/eluser]
How do I handle a join with multiple conditions in DMZ style?

This is the query that I want as a result:
Code:
SELECT
    n.*
FROM products n
LEFT JOIN properties p
    ON p.product_id = n.id
JOIN fields f
    ON p.field_id = f.id
JOIN types t
    ON n.type_id = t.id
JOIN categories w
    ON n.category_id = w.id
WHERE f.name = '".$field."'
AND p.value = '".$value."'
AND p.version = n.version
AND t.name = '".$type_name."'
AND w.id = '".$category_id."'

Thanks again!

Jeffrey

[eluser]OverZealous[/eluser]
@Jeffrey Lasut
You just query them, like in AR.
You might be wondering about deep relationships. It's in the docs, but here's an example:
Code:
// get your category first, because you can only run one query at a time.
$category = new Category($category_id);

$p = new Product();
// Distinct is optional, unless you get duplicated results due to the deep relationship
$p->distinct();

// field is deeply related through property
$p->where_related('property/field', 'name', $field_name);
// search on type name
$p->where_related_type('name', $type_name);
// related to this specific category
$p->where_related($category);
// search on property value
$p->where_related_property('value', $value)
// This one is a bit trickier, but this might work:
// the FALSE is to prevent escaping
$p->where_related_property('version', $p->add_table_name('version'), FALSE);

// load the result
$p->get();

I'm using different methods to handle the related items. You can choose, for consistently, to always use this form instead:
Code:
where_related($related_field, $column, $value);

You can also chain the methods.

[eluser]Jeffrey Lasut[/eluser]
@OverZealous

Thanks for the reply!

It's actually easier than I expected, yesterday somehow I just couldn’t wrap my mind around it.

[eluser]OverZealous[/eluser]
Dang you fixed your typo to quick (yes, I caught it ;-) ). I was going to write a rap about D-M-Z's complex-i-ty.

:lol:




Theme © iAndrew 2016 - Forum software by © MyBB