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.
This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.
The active forums are here.
November 30, 2011 3:43pm
Subscribe [100]#121 / Jan 25, 2012 12:53pm
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.
#122 / Jan 25, 2012 12:57pm
balls.
Thanks WanWizard. Appreciate it.
#123 / Jan 26, 2012 5:55am
How would you sort by a join field value? Is that possible?
$item->language->include_join_fields()->where('id', 1)->order_by('join_name', 'asc')->get();doesn’t seems to work. Any idea? Should I loop over my result to sort or could I sort using order_by method?
#124 / Jan 26, 2012 6:38am
i have user and comment models
class User extends DataMapper
{
var $table = 'users';
var $has_many = array(
'sent_comment' => array(
'class' => 'comment',
'other_field' => 'sender'
),
'recived_comment' => array(
'class' => 'comment',
'other_field' => 'reciver'
)
);
function __construct($id = NULL)
{
parent::__construct($id);
}
}
class Comment extends DataMapper {
var $table = 'comments';
var $has_one = array(
'sender' => array(
'class' => 'user',
'other_field' => 'sent_comment'
),
'reciver' => array(
'class' => 'user',
'other_field' => 'recived_comment'
)
);
var $has_many = array(
'relatedcomment' => array(
'class' => 'comment',
'other_field' => 'comment'
),
'comment' => array(
'other_field' => 'relatedcomment'
)
);
function __construct($id = NULL)
{
parent::__construct($id);
}
}the tables
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `comments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sender_id` int(10) unsigned NOT NULL,
`reciver_id` int(10) unsigned NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `comments_relatedcomments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`comment_id` int(10) unsigned DEFAULT NULL,
`relatedcomment_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `comments_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`sender_id` int(10) unsigned DEFAULT NULL,
`sent_comment_id` int(10) unsigned DEFAULT NULL,
`reciver_id` int(10) unsigned DEFAULT NULL,
`recived_comment_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;i can add users without any problems
$user_a = new User();
$user_a->username = "user_a";
$user_a->save();
$user_b = new User();
$user_b->username = "user_b";
$user_b->save();how can i add a comment from user_a to user_b and save ?
how can i add a comment from user_b to user_a as a replay to the previous comment and save ?
edit : if anyone looked at the unedited version i corrected some errors so please look again
#125 / Jan 26, 2012 11:42am
How would you sort by a join field value? Is that possible?
Looking at the code, the DM version of order_by() always prefixes the field with the current table name, unless it is already prefixed.
So ordering on a field in a join table should be possible if you prefix it with the alias of the join table.
You could work around it by replacing the order_by() method by
public function order_by($orderby, $direction = '', $escape = TRUE)
{
$escape and $orderby = $this->add_table_name($orderby);
$this->db->order_by($orderby, $direction);
// For method chaining
return $this;
}And then pass FALSE as third parameter if you don’t want to prefix the field with the table name.
If this works for you, let me know and I’ll add it to the next release.
#126 / Jan 26, 2012 12:55pm
Many thanks for your great help WanWizard. It works like a charm. I actually ended working the other way around:
$item = $language->item->include_join_fields()->order_by('items_languages.name', 'asc', FALSE)->get();Awesome 😊
Also we could have something like this (maybe not as good in term of perf):
public function order_by($orderby, $direction = '')
{
if (count(explode('.',$orderby)==0))
$escape and $orderby = $this->add_table_name($orderby);
$this->db->order_by($orderby, $direction);
// For method chaining
return $this;
}#127 / Jan 26, 2012 3:12pm
Better then the extra parameter.
In the end I did this:
strpos($orderby, '.') === FALSE AND $orderby = $this->add_table_name($orderby);
#128 / Jan 29, 2012 1:12am
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?
#129 / Jan 29, 2012 5:41am
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
$parent = new Parent();
$parent->get_by_id(1);
$parent->delete();or are you doing something differently?
#130 / Jan 29, 2012 7:55am
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?
#131 / Jan 29, 2012 11:49am
DataMapper doesn’t create tables, but then again it also doesn’t have any definitions set in the models… 😉
#132 / Jan 29, 2012 7:47pm
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
$parent = new Parent(); $parent->get_by_id(1); $parent->delete();or are you doing something differently?
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:
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:
// 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 . '
'; // outputs: users
echo $object->table . '
'; // outputs: users
echo $this->table . '
'; // outputs: countries
echo $other_model . '
'; // 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:
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
)#133 / Jan 30, 2012 4:30am
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.
#134 / Feb 01, 2012 4:23am
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.
#135 / Feb 01, 2012 8:05pm
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
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:
[ equipment name ][manufacturer][model name]
Pump haywood super pump
Filter Generic 1000
Light NULL NULLI 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
<?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
function index()
{
$c = new Customer();
$c->get(1);
$e = new Equipment();
$e->get();
echo "first name: " . $c->first_name . "
";
foreach($e as $equip)
{
$c->customers_equipment->get_where(array('equipment_id' => $equip->id));
echo "Equipment Type: " . $equip->equipment_type . " id: " . $equip->id . "
";
echo "Manufacture Name: " . $c->customers_equipment->getManufacturerText() . "
";
echo "Model: " . $c->customers_equipment->model_name . "
";
}
}The results is
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.