I have two tables Groups and Tracking and they are connected. I wanna delete Groups records, and delete foreign key in Tracking, but i don't know how to delete or update into NULL value this foreign key. I don't wanna delete all records from Tracking. Any Idea? Thanks for help.
protected $_table_name = 'trackingGroup';
protected $_primary_key = 'trg_id';
protected $_has_many = array(
'tracking' => array(
'model' => 'Orm_tracking',
'foreign_key' => 'tr_trgId',
),
);
protected $_belongs_to = array(
'user' => array(
'model' => 'Orm_users',
'foreign_key' => 'trg_uId',
),
);
function delete(){ //my first idea
foreach($this->tracking->tr_trtId->find() as $tracking)
$tracking->delete();
parent::delete();
}
In Tracking Table I have:
tr_id int PK,
tr_uId int FK,
tr_trtId int FK,
tr_trgId int FK,
tr_dateCreate data,
tr_status Char(1)
In TrackingGroups:
trg_Id int PK,
trg_name char(40),
trg_description char(256),
trg_uId int FK
How should delete works: when user want click delete button it should delete record from TrackingGroups and also it should delete or update field tr_trgId in Tracking table, there should be NULL value in tr_trgId.
Your idea is right, to find all tracking entries use find_all() function and then set tr_trgId to null and save them.
Or you can achieve this in MySQL using Forign key events ON delete set null in Tracking table.
protected $_table_name = 'trackingGroup';
protected $_primary_key = 'trg_id';
protected $_has_many = array(
'tracking' => array(
'model' => 'Orm_tracking',
'foreign_key' => 'tr_trgId',
),
);
protected $_belongs_to = array(
'user' => array(
'model' => 'Orm_users',
'foreign_key' => 'trg_uId',
),
);
function delete(){
//my first idea
foreach($this->tracking->tr_trtId->find_all() as $tracking){
$tracking->tr_trgId= null;
$tracking->save();
}
parent::delete();
}
Related
I have 3 tree like connected tables. Their schemas as follows:
Member{
//Some column
}
Transactions{
member_id :: foreign key of member table
//Some other column
}
TransactionItems{
transaction_id :: foreign key of Transaction table
//Some other column
}
I define models like this:
class Members extends AppModel {
public $primaryKey = 'id';
public $hasOne = array(
'Transactions' => array(
'className' => 'Transactions',
'foreignKey' => 'member_id',
'dependent' => true
)
);
}
class Transactions extends AppModel {
public $primaryKey = 'id';
public $belongTo = array('Members');
public $hasOne = array(
'TransactionItems' => array(
'className' => 'TransactionItems',
'foreignKey' => 'transaction_id',
'dependent' => true
)
);
}
class TransactionItems extends AppModel {
public $primaryKey = 'id';
public $belongTo = array('Transactions');
public $belongsTo = array(
'Transactions' => array(
'className' => 'Transactions',
'foreignKey' => 'transaction_id'
)
);
}
I have a Data Array which I want to save into database. My scheme is:
Array(
[Members] = [],//Array
[Transactions] = [],//Array
[TransactionItems] = []//Array
)
The problem is that whenever I run $this->Members->saveAll($data). It save data in Member and Transactions table. But do not create data in TransactionItems table. I want to save in all 3 tables at a time.
Any help would be grateful.
Second level (and above) associations must be nested, ie the data structure needs to be:
array(
'Members' => array(),
'Transactions' => array(
'TransactionItems' => array()
)
)
A bit awkward, but that's how it works in 2.x. You can always refer to the structure that is being returned when reading data, it needs to be the same when saving it.
Furthermore you must set the deep option to true in order to be able to save second level and above associations (by default only first level associations are being saved):
$this->Members->saveAll($data, array('deep' => true));
See also
Cookbook > Models > Saving Your Data > Model::saveAssociated()
I am using Kohana 3.3 and am trying to establish relationship on my ORM tables using has_many and belongs_to . I have a users table which is defined as below
I have another table userjobs defined as below. The userjobs have a foreign key referencing user_id from `users.
In the class Model_User (extends Model_Auth_User), I have defined the relationship like
protected $_has_many = array(
'user_tokens' => array('model' => 'user_token'),
'roles' => array('model' => 'role', 'through'=> 'roles_users'),
'jobs' => array('model' => 'Userjob','foreign_key' => 'user_id' ),
);
and in the class Model_Userjob (extends ORM), the following statement is written
protected $_belongs_to = array(
'user' => array('model' => 'user')
);
However, when i try to access the jobs like below, it is throwing an exception which says that jobs is not defined in Model_User
Auth::instance()->get_user()->jobs;
I had tried dumped values of the get_user() it is not showing jobs in the protected $_has_many array.
I even tried removing user_tokens and roles from the $_has_many, but still has_many array still holds the entry for roles and user_tokens when -i printed values of get_user.
I am not sure, but I think that you should set relationship in user model like this:
protected $_has_many = array(
'user_tokens' => array('model' => 'user_token'),
'roles' => array('model' => 'role', 'through'=> 'roles_users')
);
protected $_belongs_to = array(
'jobs' => array('model' => 'userjob','foreign_key' => 'user_id' )
);
and in job model:
protected $_has_one = array(
'user' => array('model' => 'userjob', 'foreign_key' => 'user_id')
);
You need to add '->find_all()' at the end of that line. Otherwise jobs will be seen as a col.
Auth::instance()->get_user()->jobs->find_all();
Model box
public $hasMany = array('Ticket' => array(
'className' => 'Ticket',
'order' => 'Ticket.created DESC',
'foreign_key' => 'box_id'
));
Model Ticket
public $belongsTo = 'Box';
In BoxesController I get data from box table
$this->set('boxes', $this->Box->find('all'));
This function get all data from table Box and from table Ticket.
How can I get data only from one table, without join other tables?
$this->Box->recursive = -1;
$this->set('boxes', $this->Box->find('all'));
or
$this->Box->unbindModel(
array('hasMany' => array('Ticket'))
);
$this->set('boxes', $this->Box->find('all'));
More on recursive
i'm starting with Kohana 3.3 ORM trying to apply it to an existing internal project.
The project is in use, so i can't change the schema's names. The current schema definition is the following:
Table: utente
idUtente VARCHAR PK
nome VARCHAR
// other fields
Table: sessione
idSessione SERIAL PK
idUtente VARCHAR (FK to utente.idUtente)
// other fields
Table: ruolo
idRuolo SERIAL PK
nome VARCHAR
//other fields
Table: ruoloutente
idRuolo PK (FK to ruolo.idRuolo)
idUtente PK (FK to utente.idUtente)
scadenza DATETIME
// other fields
Now i defined custom table name and custom primary key name into the models and if i use ORM::factory('Utente', 'Marco'); (or any other model) everything is going fine.
class Model_Utente extends ORM {
protected $_table_name ='utente';
protected $_primary_key ='idUtente';
protected $_has_many =
array(
'ruoli' => array(
'model' => 'Ruolo',
'far_key' => 'idRuolo',
'foreign_key' => 'idUtente',
'through' => 'ruoloutente',
),
'sessioni' => array(
'model' => 'Sessione',
'far_key' => 'idSessione',
'foreign_key' => 'idUtente',
),
);
// class logic here
}
class Model_Ruolo extends ORM {
protected $_table_name ='ruolo';
protected $_primary_key ='idRuolo';
protected $_has_many =
array(
'utenti' => array(
'model' => 'Utente',
'far_key' => 'idUtente',
'foreign_key' => 'idRuolo',
'through' => 'ruoloutente',
),
);
// class logic here
}
class Model_Sessione extends ORM {
protected $_table_name ='sessione';
protected $_primary_key ='idSessione';
protected $_belongs_to =
array(
'utente' => array(
'model' => 'Utente',
'far_key' => 'idUtente',
'foreign_key' => 'idUtente',
),
);
// class logic here
}
Now from an instance of Utente i execute $this->ruoli->find_all() and $this->sessioni->find_all() but i obtain an empty model on both..
The generated query is correct on both finding, query executed directly in SQL returns 4 results on ruoli and two results on sessioni..
Found a solution
My problem was that i supposed that find() and find_all() methods would also perisist in the caller object the query results instead of only return the result. Many thanks to every one
I've got some trouble trying to make this work. I have 2 models, User_Pro and Category. I read the relationships documentation on kohana guide and I understand i need to define a $_has_many relationship on the User_Pro and Category models and create the model user_pro_categories with the belongs_to field.
User_Pro model:
protected $_has_many = array(
'categories' => array(
'model' => 'TM_Category',
'through' => 'user_pro_categories',
'foreign_key' => 'id_user_pro',
),
);
Category model:
protected $_has_many = array(
'users_pro' => array(
'model' => 'TM_User_Pro',
'through' => 'user_pro_categories',
'foreign_key' => 'id_category',
),
);
user_pro_categories model:
protected $_belongs_to = array(
'user_pro' => array(
'model' => 'TM_User_Pro',
'foreign_key' => 'id_user_pro',
),
'category' => array(
'model' => 'TM_Category',
'foreign_key' => 'id_category',
),
);
The error I'm getting is:
Database_Exception [ 1054 ]: Unknown column 'tm3_user_pro_categories.category_id' in
'on clause' [ SELECT `tm3_tm_category`.* FROM `tm3_categories` AS `tm3_tm_category` JOIN
`tm3_user_pro_categories` ON (`tm3_user_pro_categories`.`category_id` = `tm3_tm_category`.`id_category`)
WHERE `tm3_user_pro_categories`.`id_user_pro` = '2' ]
It's like it doesn't care about the fk's i defined and it want's to use the suffix thing... any idea?
Here is the example to give you quick idea how Kohana ORM works. And wish it will be helpful for others too.
Student Model
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Student extends ORM {
protected $_primary_key = 'idstudent'; // take a look
protected $_has_many = array(
'courses'=> array(
'model' => 'course', // Course model
'through' => 'students_courses', // many-to-may through
'far_key' => 'id_for_course', // "column name" relating to the Course Model in "students_courses" table
'foreign_key' => 'id_for_student' // "column name" relating to the Student Model in "students_courses" table
),
);
}
Course Model
<?php defined('SYSPATH') or die('No direct script access.');
class Model_Course extends ORM {
protected $_primary_key = 'idcourse'; // take a look
protected $_has_many = array(
'students'=> array(
'model' => 'student',
'far_key' => 'id_for_student',
'through' => 'students_courses',
'foreign_key' => 'id_for_course'
),
);
}
SQL Script
CREATE TABLE IF NOT EXISTS `students` (
`idstudent` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idstudent`)
) ENGINE=MyISAM;
INSERT INTO `students` (`idstudent`, `name`) VALUES
(1, 's1'),
(2, 's2');
/* column idcourse and PR idcourseS ? */
CREATE TABLE IF NOT EXISTS `courses` (
`idcourse` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`idcourse`)
) ENGINE=MyISAM;
INSERT INTO `courses` (`idcourse`, `name`) VALUES
(1, 'c1'),
(2, 'c2'),
(3, 'c3');
CREATE TABLE IF NOT EXISTS `students_courses` (
`id_for_student` int(10) unsigned NOT NULL,
`id_for_course` int(10) unsigned NOT NULL
) ENGINE=MyISAM;
INSERT INTO `students_courses` (`id_for_student`, `id_for_course`) VALUES
(1, 1),
(1, 3);
$student = new Model_Student(1);
$courses = $student->courses->find_all();
echo Debug::vars($courses);
foreach($courses as $course) {
echo Debug::vars($course->object());
}
Running code above will create following SQL query.
SELECT `course`.* FROM `courses` AS `course` JOIN `students_courses` ON (`students_courses`.`id_for_course` = `course`.`idcourse`) WHERE `students_courses`.`id_for_student` = '1'
You don't need to create a model for pivot table for many-to-many relationship. Just define the through option in both models, make sure your primary/foreign keys follow Kohana convention and you're ready to go. Below example from Kohana ORM User and Role models:
class Model_User
{
protected $_has_many = array(
'roles' => array('model' => 'role', 'through' => 'roles_users'),
);
}
class Model_Role
{
protected $_has_many = array(
'users' => array('model' => 'user', 'through' => 'roles_users')
);
}