Welcome Guest, Not a member yet? Register   Sign In
DataMapper ORM v1.8.2
#21

[eluser]Mark Price[/eluser]
I'm having problems with the cascading deletion (auto cleanup) on one to many relationships. Rather than deleting the records in the relation table it is setting the foreign key to NULL. However, the auto cleanup works fine with my many to many relation tables.

This could be a tricky situation because there could be times when you would want it to NULL the value. For instance you might want to delete a Country but not all of the Users associated to that Country and there are times when you could have child records that are dependent on a single parent record and when the parent is deleted the children are deleted as well.

Is there a way to mark a one to many relationship as dependent or not?
#22

[eluser]WanWizard[/eluser]
Not at the moment. The next version will introduce a belongs_to relation, to indicate this dependency.

As to your problem, from a technical point of view, there is no difference in cascading deletes between a one-to-many and a many-to-many. In both cases the record on the other side has the foreign key and must be deleted. In case of a one-to-many, that is the record itself, in case of a many-to-many it is the relationship record.

You just do
Code:
$parent = new Parent();
$parent->get_by_id(1);

$parent->delete();
or are you doing something differently?
#23

[eluser]Unknown[/eluser]
Hi everyone.. I am new to codeigniter and ORM's so i am interested in trying this one. My question is, in order to use this must I already have existing tables in my DB? or can it create them for me from the definitions set in the models?
#24

[eluser]WanWizard[/eluser]
DataMapper doesn't create tables, but then again it also doesn't have any definitions set in the models... Wink
#25

[eluser]Mark Price[/eluser]
[quote author="WanWizard" date="1327833710"]Not at the moment. The next version will introduce a belongs_to relation, to indicate this dependency.

As to your problem, from a technical point of view, there is no difference in cascading deletes between a one-to-many and a many-to-many. In both cases the record on the other side has the foreign key and must be deleted. In case of a one-to-many, that is the record itself, in case of a many-to-many it is the relationship record.

You just do
Code:
$parent = new Parent();
$parent->get_by_id(1);

$parent->delete();
or are you doing something differently?[/quote]

It is setting my foreign keys to NULL in my one to many relations but, I think Datamapper is supposed to and I would prefer that it delete these records.

Here is my setup:
Code:
class Countries_model extends DataMapper
{
    public $table = "countries";
    public $has_many = array(
        'users' => array(
            'class' => 'users_model',
            'other_field' => 'country',
            'join_self_as' => 'country',
        ),
    );
}

class Users_model extends DataMapper
{
    public $table = "users";
    public $has_one = array(
        'country' => array(
            'class' => 'countries_model',
            'other_field' => 'users',
            'join_other_as' => 'country',
        ),
    );
}

$Country = new Countries_model();
$Country->get_by_id('1');
$Country->delete();

After doing some debugging and checking the condition in function delete() that is doing the update NULL this is what I get:
Code:
// We have to just set NULL for in-table foreign keys that
// are pointing at this object
if($relationship_table == $object->table  && // ITFK
         // NOT ITFKs that point at the other object
         ! ($object->table == $this->table && // self-referencing has_one join
            in_array($other_model . '_id', $this->fields)) // where the ITFK is for the other object
        )
{

echo $relationship_table . '<br />'; // outputs: users
echo $object->table . '<br />'; // outputs: users
echo $this->table . '<br />'; // outputs: countries
echo $other_model . '<br />'; // outputs: users
print_r($this->fields); // outputs: array([0] => id [1] => country)
exit;

Shouldn't the "!" be removed from the second part of the condition so that it reads:
Code:
if($relationship_table == $object->table  && // ITFK
         // NOT ITFKs that point at the other object
         ($object->table == $this->table && // self-referencing has_one join
            in_array($other_model . '_id', $this->fields)) // where the ITFK is for the other object
        )
#26

[eluser]WanWizard[/eluser]
This code has been in DataMapper for as long as I can remember.

Looking at the delete() method in general, I'm not happy with that code at all. Ideally, you want cascading deletes to work, period. No matter what kind of relationship it is, and no matter how deep it goes.

Currently, if you have a self-relationship, it doesn't delete. And if you have a parent-child-grandchild type of relation, it deletes the children when you delete the parent, leaving the grandchildren in an orphant state (due to the delete query on the relation, which doesn't look further than the direct relation).

Ideally, to do this properly, you have to fetch the related records, and call delete() on them, so they can cascade as well. Downside is that it might be a lot of instantiations and queries, and therefore slow, but I think in terms of database consistency, this is what you want.

Also, when you disable cascading deletes now, Datamapper doesn't do anything. This was done so that you could implement ON CASCADE on the table, but there is no way to say "I don't want to delete, just break the relation". Which is basically the difference between as "has" relation and a "belongs_to" relation.

I'm not sure what should be done about this. I would prefer postponing this for 2.0, which will be a complete rewrite anyway.
#27

[eluser]Spir[/eluser]
Some people on the IRC asked for help with setting CI 2.1.0 + HMVC + Datampper 1.8.2
So I made a boostrap. Here is a link:
http://www.mediafire.com/?0sxux8p46dvdduw

Hope it helps.
#28

[eluser]toadies[/eluser]
Hello, I'm working on trying to create a has_many relations with multiple tables and I think I found a solution, but since I'm very new at this I want to see if this is really a realistic way of doing this.

My tables
Code:
customers ->
  id,
  first_name,
  last_name,
  ect....

equipments ->
  id,
  equipment_type,
  equipment_group

manufacturers ->
  id,
  name

customers_equipments ->
  id,
  customer_id,
  equipment_id,
  model_name,

What I want to acheive is a list of all equipment types and related manufacture / model for each customer_id.

for example:
Code:
[ equipment name ][manufacturer][model name]
  Pump              haywood       super pump
  Filter            Generic       1000
  Light             NULL          NULL

I can do with with a SQL query, but I was trying to avoid that and use the great ORM I have learned about. Here is my code.

Customer, Equipment, and Manufacturer class has a $has_many relations with customers_equipments.

customers_equipment.php model
Code:
&lt;?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Customers_equipment extends DataMapper {

var $has_one = array('customer','equipment','manufacturer');
var $has_many = array();

var $validation = array();

function __construct()
{
  parent::__construct();
}

function getManufacturerText()
{
  $this->manufacturer->get();
  
  return $this->manufacturer->name;
}
}

the controller
Code:
function index()
{
  $c = new Customer();
  $c->get(1);
  
  $e = new Equipment();
  $e->get();

  echo "first name: " . $c->first_name . "<br />";
  foreach($e as $equip)
  {
   $c->customers_equipment->get_where(array('equipment_id' => $equip->id));
  
   echo "Equipment Type: " . $equip->equipment_type . " id: " . $equip->id . "<br />";
   echo "Manufacture Name: " . $c->customers_equipment->getManufacturerText() . "<br />";
   echo "Model: " . $c->customers_equipment->model_name . "<br />";
  }
}

The results is
Quote:first name: Christopher
Equipment Type: Pump id: 1
Manufacture Name: Hayward
Model: Turbo Jet
Equipment Type: Booster Pump id: 2
Manufacture Name: Pentair
Model: Filter 10000
Equipment Type: Filter id: 3
Manufacture Name:
Model:
Equipment Type: Heater id: 4
Manufacture Name:
Model:

I get my results, but I want to know if this is the best way or is there an easy way for ORM to do this for me.
#29

[eluser]WanWizard[/eluser]
This works, but fires an awful lot of queries.

If you need related information and you need to loop over a resultset, it's usually best to add the required fields to the query using include_related().

Also note that Datamapper does not support threeway relations. Functionally it works fine, as you have noticed, but the relational logic can not deal with it.

Which means that if you delete a parent record, Datamapper will delete the relationship record that links the parent to the other tables. Regardless of the fact that the other two tables still need that record to define the relationship between them.

You have to be aware of this fact.

If you want to do this the safe way, include the relationship table as a normal table. Make a model for it, and define the relationship between the three models and the relationship model as one-to-many.
#30

[eluser]diZzyCoDeR[/eluser]
[quote author="WanWizard" date="1327514028"]You'll have to do something about your platform.

Even if this is going to work, DataMapper will not accept it. It needs the 'id' to be an integer, it uses casting (to int) or intval() at several places in the code.[/quote]

Hmm.. this is going to be a problem. PHP does not officially support 64bit and although you can compile for it, MS doesn't have a 64bit PHP SQL driver.

#fail

How much tweaking do you think would be involved in the DM core? Like, wouldn't it be just changing the casting type to bigint..? Everything else would fall into place. (bigint would probably be for the best regardless).

*EDIT: note, the #fail is a PHP/MS #fail, not in reference to what you do! lol.




Theme © iAndrew 2016 - Forum software by © MyBB