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
Related
I want to use a single Model file for multiple tables.
Why???
The Table structure of all the tables is same
I have few columns to be stored as JSON Arrays and I would like to use Laravel's built in Json Serialization rather than manually serializing Arrays.
I have already read on laracast blog that it's not possible in Laravel but is there any other way to make it possible.
Thanks in advance!!!
You can just create a base model that has the logic that is common to all the models, and then create your individual models that inherit from the base model.
class Auto extends Model
{
protected $casts = [
'details' => 'json',
];
public function getWheelsAttribute()
{
return $this->details->wheels;
}
}
class Car extends Auto
{
// models your "cars" table
}
class Truck extends Auto
{
// models your "trucks" table
}
class Bus extends Auto
{
// models your "buses" table
}
Or, you could create a trait with the common functionality and use the trait in all your child models.
trait HasJsonDetails
{
protected $casts = [
'details' => 'json',
];
public function getWheelsAttribute()
{
return $this->details->wheels;
}
}
class Car extends Model
{
// models your "cars" table
use HasJsonDetails;
}
class Truck extends Model
{
// models your "trucks" table
use HasJsonDetails;
}
class Bus extends Model
{
// models your "buses" table
use HasJsonDetails;
}
Or, another option, if the table structure truly is and will always be the same, would be to combine all your tables into one table and use single table inheritance to have multiple models all use the same table.
With this method, you would add a type field to your table to tell you which class to use to model the individual row. It also requires some customization, but you can find an STI package to use, or follow this forum thread for more information:
https://laravel.io/forum/02-17-2014-eloquent-single-table-inheritance
This, of course, would still need to be combined with one of the methods mentioned above to share implementation logic across the multiple models.
I have successfully created a few relations in a Model. This is the user-model
<?php
class User extends BaseModel{
protected $table = 'users';
public function group(){
return $this -> belongsTo('UserGroup');
}
...
}
?>
and this is the UserGroup-model (UserGroup.php)
<?php class UserGroup extends BaseModel{ ... } ?>
Every user can be in one group (the database-column is called 'group_id' in the users-table). If I want to do eager loading on this relation, it works perfectly fine, also for other models.
The problem is that I have a few models that have a lot of foreign keys and I don't want to create all relations manually. I want a function in the BaseModel that creates all those relations automatically, like
public function group(){
return $this->belongsTo('Group');
}
based on an array that I would provide in each model, looking like this
protected $foreignKeys = array(array('key' => 'group', 'model' => 'UserGroup'), ...);
I have read that there is an array called 'with' that you can use, but it did not work for me. Somewhere else I read I should work with query scopes but I have no idea how that could help me.
Thanks for reading and your support!
Best regards, Marcel
Ardent provides something like you'd want to implement: https://github.com/laravelbook/ardent/blob/master/src/LaravelBook/Ardent/Ardent.php#L347-L350.
As per comments:
You might find Ardent-like solution better for your situation in the end. Having all the relations in an array presents more advantages to defining them as methods - you can search through those arrays if you need etc. So probably this is the way to go for you
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
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".
is there any chance to set a where statement on any select() request regarding a Zend Db Table Abstract Object?
Example:
We have 2 roles, 1 role 'admin' which is allowed to see all products and 1 role 'supplier' which is allowed to see only their own products.
I don't want to check the role and set the where statement for the Zend Db Table Abstract Object in every ActionController. Is there any chance to do this in the Zend Db Table Abstract?
class ProductsModel extends Zend_Db_Table_Abstract
{
protected $_name = 'artikel';
protected $_primary = 'ID';
protected $_where = ('supplier = ?', $this->_auth->Role ); # SOMETHING LIKE THAT ??
}
Thanks!
M.
There are two definitions in ZF: Model and Table. You should not substitute them. The model describes abstract layer between Controller and Table. The model may work with Table by means of Mapper where you can implement all business logic (where clauses, order, limit and so on).
It all are included into standart ZF example template.