Phalcon - Implement One-To-Many self-referencing relationship in model - php

How to implement this feature in the Phalcon? Doctrine has this. I want something similar like that. My office table in the database:
Id (PK) | ParentId | Name
I want a function like:
Office::findFirst()->children();
I've tried to define a Many-to-One relationship in my model but it always returns an empty array.

In your model:
namespace Models;
class ProductCategories extends BaseModel
public function initialize()
{
$this->hasMany('id', 'Models\ProductCategories', 'parent_id', [
'alias' => 'children',
'params' => [
'order' => 'position ASC',
'conditions' => 'active = 1',
]
]);
}
}
Note the full namespace.
Usage:
$parent = \Models\ProductCategories::findFirst();
print_r($parent->children->toArray());
More info: https://docs.phalconphp.com/en/3.1/db-models-relationships

Related

How to display a complex relationship field for Laravel Backpack?

I have a relationship
Candidate -> Vacancy -> User
Candidate:
class Candidate extends Model
{
public function vacancy()
{
return $this->belongsToMany(
Vacancy::class,
'vacancy_has_candidate',
'candidate_id',
'vacancy_id'
);
}
}
Vacancy:
class Vacancy extends Model
{
public function candidate()
{
return $this->belongsToMany(
Candidate::class,
'vacancy_has_candidate',
'vacancy_id',
'candidate_id'
);
}
public function manager() {
return $this->hasMany(User::class, 'manager_id');
}
}
User:
class User extends Authenticatable
{
public function vacancy()
{
return $this->belongsTo(Vacancy::class, 'manager_id');
}
}
I want to display in СRUD candidates the field of the relationship in which I call the manager method with the output of the field from the User model.
for example
class CandidateCrudController extends CrudController
{
....
public function setupCreateOperation()
{
$this->crud->addFields([
[
'name' => 'vacancy',
'type' => 'relationship',
'label' => 'Vacancy',
'model' => Vacancy::class,
'entity' => 'manager', <- this method in Vacancy model
'attribute' => 'title', <- this column name in User
'ajax' => true,
]
]);
...
I get an error
"Looks like field vacancy is not properly defined. The manager() relationship doesn't seem to exist on the App\Models\Candidate model"
I can’t understand why the backpack is looking for a manager method in Candidates, although in the model I indicated a Vacancy in which this relationship method exists. And how to do it right?
KorDEM.
You will not be able to achieve that as per Backpack Documentation:
entity is the method that defines the relationship on the current model, in your case App\Models\Candidate is the CrudController model. So entity there should be the vacancy relation.
If you are using Backpack\PRO paid addon you should be able to list the vacancies with the desired information by using something like:
$this->crud->addField([
'name' => 'vacancy',
'subfields' => [
['name' => 'manager']
]
]);
If you need aditional pivot fields you need to provide ->withPivot in the relation.
Check BelongsToMany documentation on Backpack website

CakePhp 2.5 $belongsTo in two models

Right now I have this:
Groups
Inside Groups we have Subgroups
Inside Subgroups we have Comments
Subgroups belongs to Groups 1, 2, 3 ; subgroups table have group_id field
Comments belongs to Subgroups A, B, C ; comments table have subgroup_id field
My models:
CommentsGroup.php
<?php
App::uses('AppModel', 'Model');
class CommentsGroup extends AppModel {
public $useTable = 'comment_groups';
}
CommentsSubGroup.php
<?php
App::uses('AppModel', 'Model');
class CommentsSubGroup extends AppModel {
public $useTable = 'comment_subgroups';
public $belongsTo = array(
'CommentsGroup' => array(
'className' => 'CommentsGroup',
'foreignKey' => false,
'conditions' => ['`CommentsGroup`.`id` = `CommentsSubGroup`.`group_id`']
)
);
}
Comment.php
<?php
App::uses('AppModel', 'Model');
class Comment extends AppModel {
public $belongsTo = array(
'CommentsSubGroup' => array(
'className' => 'CommentsSubGroup',
'foreignKey' => false,
'conditions' => ['`CommentsSubGroup`.`id` = `Comment`.`subgroup_id`']
)
);
}
When I try from my controller to get the subgroup_id related to the comment it's ok. When I try to get more (the group_id linked to the subgroup_id), I fail.
Query without recursive is ok, otherwise I have:
$data = $this->_Model->find('all', ['conditions' => ['subgroup_id' => $id], 'recursive' => 2, 'order' => [$this->_Modelname . '.id' => 'DESC']]);
Take in consideration $this->_Model equals to Comment .
The error I have:
Database Error Error: SQLSTATE[42S22]: Column not found: 1054 Unknown
column 'CommentsSubGroup.group_id' in 'where clause'
SQL Query: SELECT CommentsGroup.id, CommentsGroup.name FROM
botobot_comments.comment_groups AS CommentsGroup WHERE
CommentsGroup.id = CommentsSubGroup.group_id
Any guess ? Or I am wrong and I should use $hasMany relationship ?
Thanks.
You are correct in using a belongsTo relationship but you need to specify the foreignKey attribute in order for the relationships to work. You also need to take the join condition out of the conditions key (as Cake can figure that out based on the foreign key).
For example:
App::uses('AppModel', 'Model');
class Comment extends AppModel {
public $belongsTo = array(
'CommentsSubGroup' => array(
'className' => 'CommentsSubGroup',
'foreignKey' => 'subgroup_id'
)
);
}
You also need to follow Cakes naming convention with your models and tables otherwise youll need to explicitly declare your table names and primary keys in their respective models.
In your case, CommentsSubGroup should be CommentSubGroup which would assume the table called comment_sub_group and a primary key of comment_sub_group_id

Access Foreign Tables CakePHP

I am sorry if the title is a bit confusing, I just don't know how this is properly called. I have a table structure like this for my CakePHP project.
users id, name, surname, userrecords
userrecords id, user_id, records_id
records id, description
I understand that to access the userrecords middle table in my users view I have to do something like
$user['userrecords']['id'];
How can I neatly access description in records table through a users view?
You didn't specify whether you're using CakePHP 2.x or 3.x, so I provided solutions for both.
The relationship you are referring to is called a "Has And Belongs To Many" relationship. Since both of your model are associated to a linking table (userrecords), you can freely associate as many records to as many users as you want.
First, I would consider renaming your 'userrecords' table to 'users_records' to play nicely with CakePHP.
First, define your relationship within your Users model:
// Using CakePHP 2.x:
class User extends AppModel {
public $actsAs = array('Containable'); // Instantiate Containable behavior
public $hasAndBelongsToMany = array(
'Record' =>
array(
'className' => 'Record',
'joinTable' => 'users_records',
'foreignKey' => 'user_id',
'associationForeignKey' => 'record_id'
)
);
}
// Using CakePHP 3.x:
class UsersTable extends Table
{
public function initialize (array $config)
{
$this->belongsToMany('Records', [
'joinTable' => 'users_records' // Defines our linking table
]);
}
}
Now, we must define our relationship within our Records model:
// Using CakePHP 2.x:
class Record extends AppModel {
public $actsAs = array('Containable'); // Instantiate Containable behavior
public $hasAndBelongsToMany = array(
'User' =>
array(
'className' => 'User',
'joinTable' => 'users_records',
'foreignKey' => 'record_id',
'associationForeignKey' => 'user_id'
)
);
}
// Using CakePHP 3.x:
class RecordsTable extends Table
{
public function initialize (array $config)
{
$this->belongsToMany('Users', [
'joinTable' => 'users_records' // Defines our linking table
]);
}
}
Now, we can access the associated records freely from each model using the ORM's contain method:
// Using CakePHP 2.x:
// Getting 'User' and associated 'Record' models in Controller:
$this->loadModel('User');
$this->User->find('all', array('contain' => 'Record'));
// Getting 'Record' and associated 'User' models in Controller:
$this->loadModel('Record');
$this->Record->find('all', array('contain' => 'User'));
// Using CakePHP 3.x:
// Getting 'User' and associated 'Record' models:
$users_table = TableRegistry::get('Users');
$users = $users_table->find()->contain('Records')->all();
// Getting 'Record' and associated 'User' models:
$records_table = TableRegistry::get('Records');
$records = $records_table->find()->contain('Users')->all();
Read the Cookbook, it will make your life a million times easier:
CakePHP 2.x Containable Behavior
CakePHP 2.x Has And Belongs To Many Relationship
CakePHP 3.x belongsToMany Relationship
CakePHP 3.x Retrieving Associated Data
CakePHP 3.x Eager Loading Associations
Read this,this may be helpful for you
http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html
Because your table structure as below :
User -> UserRecord -> Record
So that you can only get [Record] via [UserRecord]
You should set recursive property in find command.
Please refer for more information about recursive at this link : what is the meaning of recursive in cakephp?
I hope this answer doesn't misunderstand your question.

Kohana has_many relationship

I'm using kohana 3.2 and I need help with has_many relationship. The table is written empty data...
So, my User_education model look like: http://gyazo.com/218139e52d85718c0d47bb802f0856fe User_personal model : http://gyazo.com/49fd4ab4fb7506cf8b7c608733a70365
and controller: http://gyazo.com/7d13dd3901870d7ad3d62c09e90a9c14 but fields in database still empty
You should specify the foreign key in your models:
class Model_User_Personal extends ORM
{
protected $_has_many = array(
'educations' => array(
'model' => 'user_education',
'foreign_key' => 'user_personal_id',
),
);
}
The same foreign key should be set in Model_User_Education:
class Model_User_Education extends ORM
{
protected $_belongs_to = array(
'user_personal' => array(
'model' => 'user_personal',
'foreign_key' => 'user_personal_id',
),
);
}

codeigniter doctrine many to many relationships

I have three tables.
User
id
Group
id
UserGroup
user_id
article_id
date_joined
Now I have three separate models to set up the relationship.
// User Model
<?php
class User extends Doctrine_Record
{
// define table columns in this function
public function setTableDefinition() {
}
// setup some options
public function setUp() {
$this->hasMany('Group as Groupss', array(
'local' => 'user_id',
'foreign' => 'group_id',
'refClass' => 'UserGroup'
));
// causes 'created_at' and 'updated_at' fields to be updated automatically
$this->actAs('Timestampable');
}
}
// Group Model
<?php
class Group extends Doctrine_Record
{
// define table columns in this function
public function setTableDefinition() {
}
$this->hasMany('User as Users', array(
'local' => 'group_id',
'foreign' => 'user_id',
'refClass' => 'UserGroup'
));
}
}
// UserGroups
<?php
class UserGroup extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('user_id', 'integer', 4, array(
'primary' => true
)
);
$this->hasColumn('achievement_id', 'integer', 4, array(
'primary' => true
)
);
$this->hasColumn('date_completed', 'timestamp', 25);
}
}
and now all i want to do is build the relationship inside my controller:
$user = Doctrine::getTable('User')->findOneByEmail('abcd123#gmail.com');
$group = Doctrine::getTable('Group')->findOneByID('1');
$user->Group = $user;
Both SQL commands are returning one result and when I run the controller I get the following error:
Fatal error: Uncaught exception 'Doctrine_Record_UnknownPropertyException' with message 'Unknown record property / related component "User" on "Group"' in
The refclass option in the User and Group classes should most likely be UserGroup and not UserGroups (Doctrine doesn't understand the difference between singular and plural). You should also invoke the parent::setUp() method in each of the setup() methods you declare.
There's an extensive amount of documentation on many-many relationships in the official manual. (Which uses the user-group relation as an example)
EDIT:
I noticed some severe problems with the code while going through it again:
Your UserGroup table has an article_id column, but no group_id column.
The declared relation to the Group model under the name Groupss, this making the relation $user->Group unknown.
Finally, you should assign the user to an array of groups like $user->Groups[] = $group

Categories