I am currently working an a Zend framework 1.12 based project. I use different modules to keep things separated as good as possible. My data is stored in a mysql database so I set up some db table models inside my project. The relation between the tables should be handled by Zend frameworks Zend_Db_Table Relationships. I added the necessary code to my classes:
class User_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
protected $_name = 'users';
protected $_primary = 'user_id';
protected $_dependentTables = array('Diagnostics_Model_DbTable_Diagnostics');
}
User_Model_DbTable_Users is the parent class and is defined inside the Users module. Diagnostics_Model_DbTable_Diagnostics is the referenced class and is defined inside the Diagnostics module.
class Diagnostics_Model_DbTable_Diagnostics extends Zend_Db_Table_Abstract
{
protected $_name = 'diagnostics';
protected $_primary = 'diagnostic_id';
protected $_referenceMap = array(
'User' => array(
'columns' => array('diagnostic_user'),
'refTableClass' => 'User_Model_DbTable_Users',
'refColumns' => array('user_id')
)
);
}
When I now try to load the referenced Diagnostics for a User row using
$row->findDiagnostics_Model_DbTable_Diagnostics();
I get an error:
File "Diagnostics\Model\DbTable\Diagnostics.php" does not exist or class "Diagnostics_Model_DbTable_Diagnostics" was not found in the
file
When I move the class Diagnostics_Model_DbTable_Diagnostics into the Users module and rename it correspondingly everthing works fine. So it seems to me as if it has something to do with classes beeing defined in different modules. None of the articles I have found during my researches could give me an answer to this.
Maybe I am missing something in the main Bootstrap.php or the application.ini.
You will need to bootstrap the module. Good info: http://akrabat.com/zend-framework/bootstrapping-modules-in-zf-1-8/
I use a simple class as below:
class Diagnostics_Bootstrap extends Zend_Application_Module_Bootstrap {
...
}
Don't bootstrap modules you don't need, I suggest reading http://www.mwop.net/blog/234-Module-Bootstraps-in-Zend-Framework-Dos-and-Donts.html
Related
The following code makes a ModelAdmin for MyDataObject. When adding a MyDataObject the edit form is empty because many_many relationships can only be seen after saving.
class TestAdmin extends ModelAdmin {
static $managed_models = array('MyDataObject');
static $url_segment = 'testadmin';
static $menu_title = 'TestAdmin';
}
class MyDataObject extends DataObject {
private static $many_many= array('MyOtherDataObjects' => 'MyOtherDataObject');
}
class MyOtherDataObject extends DataObject {
private static $db = array('Name' => 'Varchar(255)');
private static $belongs_many_many = array('MyDataObjects' => 'MyDataObject');
}
Is there any method of having the many_many relationships exist right away?
If not is there a way of creating the object and then removing it if no relationships are saved?
If I understood correctly, your Package can have many filters and one Filter can be used by different Package. Then you have many-many relation between Package and Filter. The list of the products is dynamic, you can calculate it every time.
Your users should refer to the Package somehow, so it should have a property Name and you have at least one input box to add new Package (not the blank screen as you have now).
Update
The behaviour you have described is correct and expected.The ManyManyList state is synchronised with database, so you cannot have items stored just in memory until you decide to store the list in the DB out of the box.
You could substitute the Add New button with your own implementation to automatically create new object, save it in the DB and redirect to edit screen.
Let's assume that we have module called 'UsersModule' with the following model in it:
class User extends CActiveRecord
{
// Some code here
}
We use this module in different applications and some time we want to extend User model to add some custom methods or properties to it. More over, often we want to change tables in database to store this new properties in it. But we don't want to change code in the UsersModule itself because it comes from the master repository (GitHub for ex.) and when we fix some bugs in it we want to simply update this module from repository in all our projects. At the same time we want to save custom changes made for the projects. So we have the following idea:
In UsersModule.php we do the following:
class UsersModule extends CWebModule
{
public $usersBaseClass = 'UsersBase';
}
In Users.php:
$extendClass = Yii::app()->getModule('users')->usersBaseClass;
$version = '1.0';
$usersFile = Yii::getPathOfAlias('application.runtime').'/Users_extends_'.$extendClass.'_v'.$version.'.php';
if(!file_exists($usersFile)) {
$code =<<<PHP
<?php
/**
* This is the model class for table "{{users}}".
*/
class Users extends {$extendClass}
{
/**
* Returns the static model of the specified AR class.
* #param string \$className active record class name.
* #return Users the static model class
*/
public static function model(\$className=__CLASS__)
{
return parent::model(\$className);
}
}
PHP;
file_put_contents($usersFile, $code);
}
if(!class_exists('Users', flase))
require_once($usersFile);
Also we introduce UsersBase.php:
class UsersBase extends CActiveRecord
{
// All base Users model logic is here
}
So when we use Users class somewhere in our application our code in Users.php generates real Users class that extends desired base class. In each project when we want to extend our Users model we can do the following:
In configs/main.php of the project:
'modules' =>
'users => array(
'usersBaseClass' => 'MyUsers'
)
And also we add MyUsers.php some where in our application:
class MyUsers extends UsersBase
{
// All the custom logic goes here
}
So my question is:
Is it a good idea to generate classes automatically in runtime or not?
Genrating php code during runtime could work, but not the best solution imho. You should use some kind of table inheritance.
More info:
http://www.yiiframework.com/wiki/198/single-table-inheritance/
http://learnyii.blogspot.hu/2012/04/yii-table-inheritance-single-active.html
I am new to Kohana framework. I am trying to use ORM module in Kohana.
My impression is that I have to create a model for each table I have.
Then only I could access the tables via those modules.
Is this correct? Can anyone explain the best practices about creating models for database access using ORM in Kohana?
Thanks in advance
Poomalairaj
When we talk about Kohana and ORM, yes, you pretty much need what we call an entity, or a model that will represent that table. That is the most common and recommended way to have your domain specified.
Remember that the concept of model in Kohana doesn't match the general concept out there. You can have a model that is kinda like a business logic entity, that doesn't have anything to do with the database.
To exemplify my answer, if you had a simple post application, like twitter or whatever, you would have something like this:
class Model_User extends ORM {
protected $_table_name = 'user';
protected $_primary_key = 'id';
protected $_has_many = array('posts' => array());
}
class Model_Post extends ORM {
protected $_table_name = 'post';
protected $_primary_key = 'id';
protected $_belongs_to = array('user' => array());
}
Kohana's ORM will also understand if you create your models like this:
class Model_User extends ORM {
protected $_has_many = array('posts' => array());
}
class Model_Post extends ORM {
protected $_belongs_to = array('user' => array());
}
Since it works most generally with conventions over configurations.
With that domain specified, you can access some user's posts like this:
$user->posts
And a post user (author) like this:
$post->user
Hope that can clarify your mind!
You don't have to add
protected $_primary_key = 'id';
every model you add, it is the default key, but if your key is other than 'id' you have to add the line, specifying the right key such as "userId".
I'm trying to write a very simple cms (for learning purposes) in kohana 3 web framework.
I have my db schemas and i want to map it to ORM but i have problems with relations.
Schemas:articles and categories
One article has one category. One category might has many articles of course.
I think it is has_one relationship in article table.(?)
Now php code. I need to create application/classes/models/article.php first, yes?
class Model_Article extends ORM
{
protected // and i am not sure what i suppose to write here
}
class Model_Article extends ORM{
protected $_belongs_to = array
(
'category' => array(), // This automatically sets foreign_key to category_id and model to Model_Category (Model_$alias)
);
}
class Model_Category extends ORM{
protected $_has_many = array
(
'articles' => array(), // This automatically sets foreign_key to be category_id and model to Model_Article (Model_$alias_singular)
);
}
You can also manually define the relation ;
'articles' => array('model'=>'article','foreign_key'=>'category_id');
More about Kohana 3 ORM
More about Kohana ORM naming conventions
I have a few tables that I've defined like the below examples:
class TableA extends Zend_Db_Table_Abstract
{
protected $_schema = 'schema1';
protected $_name = 'tablea';
}
class TableB extends Zend_Db_Table_Abstract
{
protected $_schema = 'schema2';
protected $_name = 'tableb';
}
This seems to work perfectly using one default Db adapter (since the 2 schemas are on the same server).
Code like this works:
$tableA = new TableA();
$select = $tableA->select();
// $select->__toString() outputs: SELECT * FROM `schema1`.`tablea`
However, when I try to use the same models with any of the Zend Framework table relationship functions (ie: findDependantRowset() or findManyToManyRowset()) the query tries to execute using the schema from the default adapter and does not use the appropriate schema that is defined in the model class.
Is this a bug? How can I force ZF to use the schema I have defined in the table class and not the one defined as the default in the default Db adapter?
I think this is related to this bug:
http://framework.zend.com/issues/browse/ZF-1838
It has been fixed in the upstream and should be available in the next release.
I think you can use a database view table to merge data from 2 schemas, and then use Zend Framework to fetch data from that table.