SQL join with Kohana ORM - php

I'm using Kohana 3.0.6 with ORM.
I have a model named "truck" and in his table there's a column with the id of his maker ("maker"). Then I have the "maker" model with the id and the name in his table.
I'm trying to do a simple LEFT-JOIN when I display the listing of the trucks so I can get directly the names of their maker.
Here is my "truck" model:
<?php defined('SYSPATH') or die('No direct access allowed.');
class Model_Truck extends ORM {
// Database settings
protected $_db = 'default';
protected $_table_name = 'trucks';
protected $_primary_key = 'id';
//Tried adding this but doesn't seems to work
protected $_has_one = array('maker' => array('model' => 'maker') );
// Table fields
protected $_table_columns = array(
'id' => array('data_type' => 'int', 'is_nullable' => FALSE),
'serial' => array('data_type' => 'string', 'is_nullable' => FALSE),
'maker' => array('data_type' => 'string', 'is_nullable' => FALSE),
'model' => array('data_type' => 'string', 'is_nullable' => FALSE),
'year' => array('data_type' => 'int', 'is_nullable' => FALSE),
);
}
As you can see, I'm using this line to add the "has_one", though I've also seen the "with()" call somewhere but couldn't make it work proprely (doc is a bit lacking, especially for version 3.x.x).
protected $_has_one = array('maker' => array('model' => 'maker') );
Here's the line I'm using in the view to output the maker name (something along those lines):
foreach ($trucks as $t) {
echo($t->maker->name);
}

Do you have the column named truck_id in the makers table?

Related

Kohana ORM - Empty Result on User Rights

Im building a user management system based on 2 pillars.
1. Roles
Each user have multiple roles.
2. Rights
Every role consists of one or more rights.
Users and roles are working fine in my attempt:
class Model_Auth_User extends ORM {
protected $_has_many = array(
'roles' => array('model' => 'Role', 'through' => 'roles_users'),
);...}
class Model_Auth_Role extends ORM {
protected $_has_many = array(
'users' => array('model' => 'User','through' => 'roles_users'),
);...}
I am trying to add some Roles and Rights the same way:
class Model_Auth_Role extends ORM {
protected $_has_many = array(
'users' => array('model' => 'User','through' => 'roles_users'),
'rights' => array('model' => 'Right','through' => 'role_rights'),
);
class Model_Auth_Right extends ORM {
protected $_has_many = array(
'roles' => array('model' => 'Role','through' => 'role_rights'),
);
The access to the roles works fine like this:
$roles = $user->roles->find_all(); //works fine
However, the access to the Rights of a Role always delivers an empty result:
$rights = $user->roles->rights->find_all();
Because $user->roles i collection
<?php
$rights = [];
foreach($user->roles->find_all() as $role){
$rights[] = $role->rights->find_all();
}

SilverStripe 3.4: How to add default records to db from model

Unable to locate in the SilverStripe Documentation how to have a DataObject Model inject a collection of default records on /dev/build
Anybody able to point me in the right direction
This is what I currently have, and obviously I would like to inject pre-configured options into this aptly named Configuration model for my Module.
class Configuration extends DataObject
{
private static $db = array(
'Option' => 'Varchar',
'Value' => 'Varchar'
);
private static $summary_fields = array(
'Option' => 'Option',
'Value' => 'Value',
);
}
Thanks in advance for any direction/pointers.
UPDATE
I was turned onto SiteConfig by #Barry below
However in following his practice, requireDefaultRecords() is not injecting defaults
Note: I have since revisited /dev/build?flush
class RMSConfiguration extends DataExtension
{
private static $db = array(
'username' => 'Varchar',
'password' => 'Varchar',
'agent_id' => 'Varchar(15)',
'client_id' => 'Varchar(15)',
'testMode' => 'Int(1)',
'timezone' => 'Varchar',
'apiUrl' => 'Varchar(255)'
);
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldsToTab(
"Root.RMSConfig",
array(
TextField::create('username', 'RMS Username'),
TextField::create('password', 'RMS Password'),
TextField::create('agent_id', 'RMS Agent ID'),
TextField::create('client_id', 'RMS Client ID'),
TextField::create('apiUrl', 'API Url'),
CheckboxField::create("testMode", 'Toggle Test Mode'),
DropdownField::create("timezone", 'Timezone', static::$timezones)
)
);
}
public function requireDefaultRecords()
{
parent::requireDefaultRecords();
$arrOptions = array(
'timezone' => 'Australia/Sydney',
'apiUrl' => 'https://api.example.com.au/',
'testMode' => 0
);
foreach ($arrOptions as $strOption => $strValue) {
if (!$configuration = self::get()->filter('Option', $strOption)->first()) {
$configuration = self::create(array( 'Option' => $strOption ));
}
$configuration->Value = $strValue;
$configuration->write();
}
}
/**
* List of timezones supported by PHP >=5.3.x
*
* #var array
*/
public static $timezones = array(
"Africa/Abidjan",
"Africa/Accra",
"Africa/Addis_Ababa",
"Africa/Algiers",
...
...
"Zulu"
);
}
Using the function requireDefaultRecords in the DataObject - this is called during every dev/build.
Note: First check if the option exists to prevent duplicates as this will be called every time you dev build.
class Configuration extends DataObject {
private static $db = array(
'Option' => 'Varchar',
'Value' => 'Varchar'
);
private static $summary_fields = array(
'Option' => 'Option',
'Value' => 'Value',
);
function requireDefaultRecords() {
parent::requireDefaultRecords();
$arrOptions = array(
'Option1' => 'Value1',
'Option2' => 'Value2',
'Option3' => 'Value3',
);
foreach ($arrOptions as $strOption => $strValue) {
if (!$configuration = Configuration::get()->filter('Option',$strOption)->first())
$configuration = Configuration::create(array('Option' => $strOption));
$configuration->Value = $strValue;
$configuration->write();
}
}
}
One final comment is that there is a module for SiteConfig which is used by SilverStripe, most modules and where I would recommend you put configuration values like this instead.
If you do choose SiteConfig then please see the function populateDefaults and documentation for it's use, this is an example...
/**
* Sets the Date field to the current date.
*/
public function populateDefaults() {
$this->Date = date('Y-m-d');
parent::populateDefaults();
}
(if the above is used in an extensions it might need $this->owner->Date instead of $this->Date)
The above function isn't needed if all the values are static, instead it will read them just from this array (again within DataObject)
public static $defaults = array(
'Option1' => 'Value1',
'Option2' => 'Value2'
);
This works on any DataObject as well, but as SiteConfig manages one record and this populates that record once upon creation this is much more convenient for to use instead of requireDefaultRecords.

drop and create tables with fixtures on cakephp

I have already seen this question:
CakePHP PHPUnit Fixtures Drop Database Table Every Time
Creating multiple fixtures in cakePhp
CakePHP Test Fixtures Drop My Tables Permanently After Running A Test Case
But this links are old I think.
I would like to create test where Im'loading fixtures so test drop tables and create it with records.
My problem is that: Tests drop taboles btu it doesn't recreate it.
This is my model where I'm loading fixtures:
App::uses('Post', 'Model');
class PostTest extends CakeTestCase {
public $fixtures = array('app.post');
public function setUp() {
parent::setUp();
$this->Post = ClassRegistry::init('Post');
}
public function testSetTemplate() {
$this->assertEquals('1', '1');
}
}
And this is my fixture file:
class PostFixture extends CakeTestFixture {
public $import = array('model' => 'Post', 'records' => true);
public $name = 'Post';
public $table = 'posts';
public $fields = array(
'id' => array('type' => 'integer', 'length' => 36, 'key' => 'primary'),
'created' => array('type' => 'datetime'),
'modifed' => array('type' => 'datetime')
);
public $records = array(
array(
'id' => '1',
'created' => '2014-01-17 12:31:41',
'modified' => '2014-07-22 09:50:42'
),
);
}
I have also tried with:
public $import = array('model' => 'Post', 'records' => false);
Same thing tests drop tables but doesn't create it.
I need to create it after drop with my records.
Where s the error? Why tests doesn't recreate it table posts but only drop it?
Thanks

Kohana - has_many and belongs_to not working properly

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();

Kohana 3.3 ORM relations

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

Categories