Saving / Creating data to associated table is not working - cakephp

I have three table,
Authors
Stories
Details
Stories and Details are associated with the Authors, with hasOne relationship.
Bellow is the code in my AuthorsController
function add(){
if($this->request->is('POST')){
$author = $this->Authors->newEntity($this->request->data,
['associated' => ['Stories', 'Details'], 'validate' => false]
);
$this->Authors->save($author);
}
}
This is only saving data in the Authors table, not in the other two table.
Bellow is the data I have in $this->request->data
'Authors' => [
'name' => 'Bikash'
'Age' => '22'
'stories' => [
'name' => 'Life Without the L'
'gener_id' => 5
]
'details' => [
'qualification' => 'XYZ'
'biography'
]
];
What I am missing?

You are using the wrong property names, stories and details won't work.
The default association property name for hasOne associations, is the underscored singular variant of the association alias, so for Stories that would story, and for Details it would be detail.
See also
Cookbook > Database Access & ORM > Associations - Linking Tables Together > HasOne Associations
Inflector Sandbox > Stories
Inflector Sandbox > Details

Related

How to add link to show action of the relation entity on relation field in SonataAdminBundle

Im making admin panel in SonataAdminBundle.
In User show action i have field companies which return array of companies assigned to the user.
It is a OneToMany relation. UserCompany has user_id and company_id.
I want to create link on each returned company name, which points to it's entity show action.
This is code from configureShowFields() function in UserAdmin class:
->with('Assigned organizers',['class' => 'col-md-6'])
->add('companies', null, [
'label' => 'Organizers',
])
->end()
I managed to create a link on a string field pointing to show action of an entity, but the id property is taken from the current entity view:
->with('Address', ['class' => 'col-md-6'])
->add('userProfile.locality', 'url', [
'route' => [
'name' => 'admin_app_employee_show',
'identifier_parameter_name' => 'id'
],
'label' => 'Localiy',
])
What's more Sonata Admin create links on related fields, when the relation is direct,
for example:
Company has many Employee. Then in Company show action on employees field
I see array with links already heading to edit action of Employee entty.
Maybe there is a possibility to override template for this field, but it seems unclear for me,
as the documentation lacks of more advanced examples.
This is how I tried to test overriding the template of a field:
->add('userProfile.street', null, array(
'label' => 'Street',
'template' => 'custom-field.html.twig',
))
Location of the template: App/templates/Admin/
Any help appreciated
SonataAdmin automatically creates links to related entities once it has all of them configured and added to services.
Then you can just change the route action of the link on the relation field as following:
->with('Assigned events', ['class' => 'col-md-6'])
->add('events', null, [
'route' => [
'name' => 'show'
],
'label' => 'Events',
])
->end()
You can also change the type of relation field eg.'many_to_one' instead of null which might help in some cases.

How to make relationships in cakephp3

I am trying to make the relationship between the tables, but can’t figure out what I doing wrong.
I read The documentations in cakephp3, and tons of post in stackoverflow, and still can’t get any result.
--------------------------
name |invoices |shares |
var |id |id |
var | |idBill |
--------------------------
The relationship should be from idBill in shares and id in invoices
class SharesTable extends Table {
public function initialize(array $config) {
parent::initialize($config);
$this->belongsTo('invoices', [
'className' => 'App\Model\Table\InvoicesTable',
'foreignKey' => 'idBill',
'targetForeignKey' => 'id'
]);
}
}
And in controller try to print the bill associate to the share like this:
public function view($id = null)
{
$share = $this->Shares->get($id, [
'contain' => []
]);
var_dump( $share->invoices );
$this->set('share', $share);
}
I just expect to print the bill but I always get null
Your contain is empty, so you won't receive any associations. Also the default entity property name for belongsTo (and hasOne) associations is the singular, underscored variant of the association name, ie invoice, not invoices.
It's also recommended to use association names that do match the table alias, that is Invoices (with a capital I) for InvoicesTable, that way it will find the class automatically and you don't have to specify it via the className option (also there is no targetForeignKey option for belongsTo associations).
$this->belongsTo('Invoices', [
'foreignKey' => 'idBill'
]);
$share = $this->Shares->get($id, [
'contain' => ['Invoices']
]);
debug($share->invoice);
See also
Cookbook > Database Access & ORM > Retrieving Data & Results Sets > Eager Loading Associations Via Contain
Cookbook > Database Access & ORM > Associations - Linking Tables Together

CakePHP 3.x - Save many-to-many data

I am attempting to patchEntity with a join table, but I am unable to get it to save the associated records, and I think I have the backend code correct, but I am unsure of what the frontend code should look like...
Here is the scenario, I have three tables
Ledgers Table
id int
title string
Tribes Table
id int
name string
LedgersTribes Table
id int
ledger_id int
tribe_id int
Here is my backend code
public function ledgerSave($id = null)
{
$this->loadModel('Ledgers');
$ledger = $this->Ledgers->get($id, [
'contain' => ['LedgersTribes']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$ledger = $this->Ledgers->patchEntity($ledger, $this->request->getData(), [
'associated' => ['LedgersTribes']
]);
if ($this->Ledgers->save($ledger)) {
$this->Flash->success(__('The ledger has been saved.'));
return $this->redirect($this->referer());
}
$this->Flash->error(__('The ledger could not be saved. Please, try again.'));
}
$this->set(compact('ledger'));
}
Here is the relevant frontend code
<?= $this->Form->control('tribe_id[]', ['type' => 'checkbox', 'label' => false, 'class' => 'minimal', 'value' => $tribe->id]) ?>
My question is, what should the field name be for the tribe_id, the idea is, i have a list of checkboxes and the user checks off a couple of boxes and then those tribe_id's get inserted into the LedgersTribes table with the ledger_id
Any ideas on how I can do this?
EDIT: Here is a screenshot of the form
I have reviewed the following links, and none of them answer my question...
CakePHP 3: Save Associated Model Fail
Save associated in cakephp 3 not working
How to save associated joinData in cakephp 3.x
CakePHP 3 cannot save associated model
Cakephp 3 - Save associated belongsToMany (joinTable)
This should do:
echo $this->Form->control('tribes._ids[]', [
'type' => 'checkbox',
'label' => false,
'class' => 'minimal',
'value' => $tribe->id]
]);
This is described here: https://book.cakephp.org/3.0/en/views/helpers/form.html#creating-inputs-for-associated-data
I think you have to get the table (ex: TableRegistry::getTableLocator()->get('')) where you want to save the data. Then create entity from that and save the data, hopefully it will work.

CakePHP: Using attributesof model in associations-condition

I have a table that has a "hasOne"-association to another table, but without any foreign key. So my "hasOne"-association finds the related entity with a customized finder-method:
$this->hasOne('HourlyRates', [
'foreignKey' => false,
'finder' => ['byShift' => ['userId' => '1', 'shiftBegin' => '2016-01-01']]
]);
My problem is, that the options for the finder have to be the attributes of the actual entity of the first table. This is the user_id of one entity and the shift-begin of one entity.
I tried
'finder' => ['byShift' => ['userId' => 'Shifts.user_id', 'shiftBegin' => 'Shifts.begin']]
But it didn't work.
So do you know, how to access the attributes of one entity in the Table-class?

Has Many relationship how to

I have this model and controller and it returns fine if it is a hasOne relationship but now DishCategory hasMany dishes. When I change the code below to hasMany it gives me an error saying Dish.id is not a known column while if it is a hasOne it works fine. How can I make it so that it returns all the Dish.id's that have id=1? (still using the join).
class DishCategory extends AppModel{
public $hasOne = array(
'Dish' => array(
'className' => 'Dish',
'foreignKey' => 'dish_category_id'
)
);
}
class DishCategoriesController extends AppController {
function get_categories($id)
{
// find category with a dish of $id
$this->set('dishes', $this->DishCategory->find('all', array(
'conditions' => array(
'Dish.id' => $id
)
)));
// set master layout
$this->layout = 'master_layout';
}
}
hasOne relations can be joined into the primary SQL query. hasMany relations cannot and need to be queried in a separate query. The conditions you specify for the query only apply to the primary query, all separate relational queries are build just based on the ids retrieved in the primary query. Set debug to 2 and have a good look at the query log to see what I mean.
To find the category of a dish, fetch the dish and look at its related category record:
$dish = $this->Dish->find('first', array('conditions' => array('Dish.id' => $id)));
echo $dish['DishCategory']['name'];
Since I take it that a dish belongsTo one category, your query "find all categories which have a dish with id x" makes little sense; there should only be one anyway.

Resources