I have 'seller_businessestable andseller_business_categories` table. I am using a single form to save values to sellers and seller_businesses.
The form is like
<?= $this->Form->create() ?>
<?= $this->Form->input('company_name') ?>
<?= $this->Form->input('logo', ['type' => 'file']) ?>
<?= $this->Form->input('seller_business_categories.category_id') ?>
<?= $this->Form->button('Submit', ['type' => 'submit']) ?>
<?= $this->Form->end() ?>
The seller_business_categories has a column seller_id and I have to save the logged in user id in it.
I know to save value to table seller_businesses in controller like
$seller_business = $this->SellerBusinesses->newEntity();
$seller_business->seller_id = $this->Auth->user('id');
$this->SellerBusinesses->patchEntity($seller_business, $this->request->data, [
'associated' => ['SellerBusinessCategories']
]);
But how to save default value to associated model SellerBusinessCategories within controller ?
You need make relationship
SellerBusinessCategorie.php MODEL
public function initialize(array $config)
{
parent::initialize($config);
$this->table('seller_business_categories');
$this->hasMany('seller_businesses', [
'foreignKey' => 'seller_id'
]);
}
SellerBusinesses.php MODEL
public function initialize(array $config)
{
parent::initialize($config);
$this->belongsTo('seller_business_categories', [
'foreignKey' => 'category_id',
'joinType' => 'INNER'
]);
}
Controller
$seller_business = $this->SellerBusinesses->newEntity();
$seller_business->seller_id = $this->Auth->user('id');
$this->SellerBusinesses->patchEntity($seller_business, $this->request->data]);
NOW TRY..it works
Related
I would like to be able to add a membership record at the same time I add a user. I can't seem to get it to work. I want to be able to select the membership level and have that data get sent to the controller where I can add the data, unless there is a way to just select the membership level and it will automatically create a membership record for the user that gets added.
The membership level contains the information for that level of membership and the membership record contains some information from the membership level and is associated to a user.
The add form I believe is where the problem lies, but just in case here are the important snippets of code. I tried to keep it as simple as possible.
Users Table Initialize Function:
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasOne('Memberships', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
}
Memberships Table Initialize Function:
public function initialize(array $config)
{
$this->table('memberships');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
'joinType' => 'INNER'
]);
$this->hasOne('MembershipLevels', [
'foreignKey' => 'membership_level_id',
'joinType' => 'INNER'
]);
}
Users Controller Add Method:
public function add()
{
$user = $this->Users->newEntity($this->request->data(), [
'associated' => [
'Memberships' => ['associated' => ['MembershipLevels']]
]
]);
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data(), [
'associated' => [
'Memberships' => ['associated' => ['MembershipLevels']]
]
]);
if ($$this->Users->save($user)) {
$this->Flash->success(__('You have been added.'));
} else {
$this->Flash->error(__('You could not be added. Please, try again.'));
}
}
$membershipLevels = $this->Users->Memberships->MembershipLevels->find('list', ['limit' => 200]);
$this->set(compact('user', 'membershipLevels'));
$this->set('_serialize', ['user', 'membershipLevels']);
}
Add Users Form:
<div class="form">
<h1>Join Now</h1>
<?= $this->Form->create($user); ?>
<fieldset>
<legend><?= __('User Info') ?></legend>
<?= $this->Form->input('full_name', ['required' => false]); ?>
<?= $this->Form->input('username', ['required' => false]); ?>
<?= $this->Form->input('email', ['required' => false]); ?>
<?= $this->Form->input('password', ['required' => false]); ?>
<?= $this->Form->input('password_confirmation', ['type' => 'password', 'required' => false]); ?>
<?php
if ($current_user['role'] === 1 && isset($logged_in)) {
echo $this->Form->input('role', ['type' => 'select', 'options' => ['1' => 'Admin', '2' => 'Editor', '3' => 'Author', '4' => 'Reader'], 'default' => '4']);
}
?>
</fieldset>
<fieldset>
<legend><?= __('Membership Info') ?></legend>
<?= $this->Form->label('Membership Level'); ?>
<?= $this->Form->input('memberships.membership_levels._id', ['options' => $membershipLevels, 'required' => false]); ?>
</fieldset>
<?= $this->Form->button(__('Sign Up'));?>
<?= $this->Form->end();?>
</div>
I changed the code a bit thanks to the comments and answers. The membership levels now show up in the form and I pick a membership level when saving the user, but the membership doesn't get saved as well, just the user. Any further suggestions?
How about start reading the migration guide, or doing the blog tutorial for CakePHP3? Your trial and error approach is time consuming and frustrating. I can't recommend this enough: Always read documentation before shooting in the darkness. There has a lot changed in CakePHP3. This includes the way the dot notation is used. Reading saving associations might help as well.
You don't use any longer the model prefix on the first level.
Model.field
is now just
field
For nested associations it's now
associated_data.field
associated_data.second_level_data.field
Notice that this is inflected and singular or plural depending on the kind of association.
I have updated my code to get the closest I can to getting all the automagic to work.
Key points:
1.) In controller I got the membership levels variable to pass to the view by adding this line. (notice the calling of the users table then memberships and then membershiplevels).
$membershipLevels = $this->Users->Memberships->MembershipLevels->find('list', ['limit' => 200]);
2.) In the view I added:
<?= $this->Form->input('memberships.membership_levels._id', ['options' => $membershipLevels, 'required' => false]); ?>
This is not a complete answer however because I still have to grab the membership level in the controller with a query and then manually save the data from that level to the memberships table.
I can at least populate the membership level input in the form dynamically and submit it.
I had looked over the bookmarker tutorial that I had previously done since it uses associations, but with that tutorial they are able to add the bookmarks_tags record automatically when you add a bookmark and I am not sure if it is due to the functions in the table files or not.
I have Problems and Fields in a many-to-many relationship. The join table fields_problems has a field named fieldvalue I am trying to have a form that will insert a problem record and also multiple records into fields_problems.
/src/Model/Table/ProblemsTable.php
class ProblemsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('problems');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsToMany('Fields', [
'foreignKey' => 'problem_id',
'targetForeignKey' => 'field_id',
'joinTable' => 'fields_problems'
]);
}
...
/src/Model/Table/FieldsTable.php
class FieldsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('fields');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsToMany('Problems', [
'foreignKey' => 'field_id',
'targetForeignKey' => 'problem_id',
'joinTable' => 'fields_problems'
]);
}
...
/src/Model/Table/FieldsProblemsTable.php
class FieldsProblemsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('fields_problems');
$this->displayField('id');
$this->primaryKey('id');
$this->belongsTo('Fields', [
'foreignKey' => 'field_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Problems', [
'foreignKey' => 'problem_id',
'joinType' => 'INNER'
]);
}
...
And I want to Add a new problem, link it to fields, and add values to the fieldvalue field in the join table.
So I have this /src/Template/Problems/add.ctp
<div class="problems form large-10 medium-9 columns">
<?= $this->Form->create($problem) ?>
<fieldset>
<legend><?= __('Add Problem') ?></legend>
<?php
echo $this->Form->input("Problems.id");
echo $this->Form->input('Problems.summary');
echo $this->Form->input('Problems.Fields.0._ids', [
'type' => 'select',
'multiple' => false,
'options' => $fields,
]);
echo $this->Form->input('Problems.Fields.0._joinData.fieldvalue');
echo $this->Form->input('Problems.Fields.1._ids', [
'type' => 'select',
'multiple' => false,
'options' => $fields,
]);
echo $this->Form->input('Problems.Fields.1._joinData.fieldvalue');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
And this add() in /src/Controller/ProblemsController.php
public function add()
{
$problem = $this->Problems->newEntity();
if ($this->request->is('post')) {
$problem = $this->Problems->patchEntity($problem, $this->request->data, ['associated'=>['Fields._joinData']] );
//$problem->dirty('fields',true);
if ($this->Problems->save($problem)) {
$this->Flash->success(__('The problem has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The problem could not be saved. Please, try again.'));
}
}
$fields = $this->Problems->Fields->find('list', ['limit' => 200]);
$this->set(compact('problem', 'fields'));
$this->set('_serialize', ['problem']);
}
When I fill out and submit the app form, the Problem record is saved, but the association is not, nothing gets inserted into fields_problems.
What am I doing wrong that is preventing the associated joinData from being saved?
Despite the cookbook (http://book.cakephp.org/3.0/en/views/helpers/form.html) saying to use the special _ids key, don't!
Changing "_ids" to "id" fixed the form and now it functions properly saving the data into the jointable.
Here is the example from the cookbook that I built my app with
echo $this->Form->input('tags.0.id');
echo $this->Form->input('tags._ids', [
'type' => 'select',
'multiple' => true,
'options' => $tagList,
]);
Here is how it should be
echo $this->Form->input('tags.0.id', [
'type' => 'select',
'multiple' => false,
'options' => $tagList,
]);
I am saving an Employee which is associated with a hasMany relationship with Courses through EmployeesCourses table. This all works fine, the employee gets added and the new employee_id and the course_id get created into EmployeesCourses table.
I am now trying to add a record into the users table for the employee and the new user_id gets saved with the employee as it gets created. All other recored still get saved but I do not get anytime for the users table and no id in Employee.user_id
EmployeesController.php
public function add()
{
$employee = $this->Employees->newEntity();
if ($this->request->is('post')) {
$employee = $this->Employees->patchEntity($employee, $this->request->data, [
'associated' => ['Users', 'Courses']
]);
if ($this->Employees->save($employee)) {
$this->Flash->success(__('The employee has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The employee could not be saved. Please, try again.'));
}
}
$businesses = $this->Employees->Businesses->find('list', ['limit' => 200]);
$courses = $this->Employees->Courses->find('list', ['limit' => 200]);
$this->set(compact('employee', 'users', 'businesses', 'courses'));
$this->set('_serialize', ['employee']);
}
employees add.ctp
<?= $this->Form->create($employee) ?>
<fieldset>
<legend><?= __('Add Employee') ?></legend>
<?php
echo $this->Form->input('user.email');
echo $this->Form->input('user.new_password', ['value' => '', 'type' => 'password']);
echo $this->Form->input('user.confirm_password', ['value' => '', 'type' => 'password']);
echo $this->Form->input('business_id', ['options' => $hotels]);
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('surname');
echo $this->Form->input('employee_num');
echo $this->Form->input('courses._ids', ['options' => $courses]);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
Employees Model
public function initialize(array $config)
{
$this->table('employees');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
]);
$this->belongsTo('Businesses', [
'foreignKey' => 'hotel_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Courses', [
'foreignKey' => 'employee_id',
'targetForeignKey' => 'course_id',
'joinTable' => 'courses_employees'
]);
}
Users model
public function initialize(array $config)
{
$this->table('users');
$this->displayField('email');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Roles', [
'foreignKey' => 'role_id'
]);
$this->hasOne('Employees', [
'foreignKey' => 'user_id'
]);
$this->hasOne('Businesses', [
'foreignKey' => 'user_id'
]);
}
I have a Users model which has a hasOne relationship to an Employees model. When I save a user I also add a record in the Employees table with the user_id. This works fine.
The Employee can be associated to belongsToMany Courses through CoursesEmployees table. This saves ok when I only save the Employees.
My problem is I want to save all 3 three but the Courses do not get saved.
Save user -> save employee with new user_id -> save courses chosen for new employee with employee_id in courses_employees
EmployeesTable.php
public function initialize(array $config)
{
$this->table('employees');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Users', [
'foreignKey' => 'user_id',
]);
$this->belongsTo('Hotels', [
'foreignKey' => 'hotel_id',
'joinType' => 'INNER'
]);
$this->belongsToMany('Courses', [
'foreignKey' => 'employee_id',
'targetForeignKey' => 'course_id',
'joinTable' => 'courses_employees'
]);
}
users add.ctp:
<?= $this->Form->create($user) ?>
<fieldset>
<legend><?= __('Add User') ?></legend>
<?php
echo $this->Form->input('role_id', ['options' => $roles, 'empty' => true]);
echo $this->Form->input('email');
echo $this->Form->input('active');
echo $this->Form->input('activation_key');
echo $this->Form->input('password');
echo $this->Form->input('employee.name');
echo $this->Form->input('employee.email');
echo $this->Form->input('employee.surname');
echo $this->Form->input('employee.employee_num');
echo $this->Form->input('employee.courses._ids', ['options' => $courses]);
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
Here is the post data sent to the add method for save. With this the user and employee get saved correctly but no recored in the courses_employees.
If I save the employee form the employee controller the courses_employees get add ok so I know the associations are setup ok.
[
'role_id' => '1',
'email' => 'asdasd#asdasd.com',
'active' => '11111111111',
'activation_key' => '1',
'password' => 'asdasdadasdasdasda',
'employee' => [
'name' => 'asdasdasdasd',
'email' => 'asdasdasd2dasd.com',
'surname' => 'asdasdads',
'employee_num' => 'asdasdadasdas',
'courses' => [
'_ids' => [
(int) 0 => '2'
]
]
]
]
UserController.php
public function add()
{
$this->loadModel('Courses');
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data, [
'associated' => ['Employees', 'Courses']
]);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$roles = $this->Users->Roles->find('list', ['limit' => 200]);
$courses = $this->Courses->find('list', ['limit' => 200]);
$this->set(compact('user', 'roles', 'courses'));
$this->set('_serialize', ['user']);
}
I have found the solution. I have read the cookbook again and I noted in one of the examples snippets 'associated' => ['Tags', 'Comments.Users']
I have applied this to my controller and it now works. It is saving on all levels.
$user = $this->Users->patchEntity($user, $this->request->data, [
'associated' => ['Employees', 'Employees.Courses']
]);
I am trying to associate multiple games to a continuity in my database.
I have 3 tables: continuities, continuities_games and games. The continuities_games table has a continuity_id and a game_id. When I try to select the different games in my selection input, it creates a new game entry in the database and then creates a entry into the join table linking it to that new game entry instead of linking it to the originally selected game.
This is the initialize function in my ContinuitiesTable:
public function initialize(array $config){
parent::initialize($config);
$this->belongsToMany('Games');
}
And for my GamesTable:
public function initialize(array $config){
parent::initialize($config);
$this->displayField('name');
$this->addBehavior('Tree');
//Associations
$this->hasMany('Children', [
'className' => 'Games',
'foreignKey' => 'parent_id',
'dependant' => true,
'cascadeCallbacks' => true,
]);
$this->belongsTo('Parent', [
'className' => 'Games',
]);
$this->hasMany('Books');
$this->belongsToMany('Continuities');
}
This is my edit function in the ContinuitiesController:
public function edit($id=null){
$continuity = $this->Continuities->find()->where(['id'=>$id])->contain('Games')->first();
if ($this->request->is(['post', 'put'])) {
debug($this->request->data);
$continuity->start_date = $this->request->data['start_date']['year'].'-'.$this->request->data['start_date']['month'].'-'.$this->request->data['start_date']['day'];
$continuity->end_date = $this->request->data['end_date']['year'].'-'.$this->request->data['end_date']['month'].'-'.$this->request->data['end_date']['day'];
//$continuity->start_date = $this->request->data['start_date'];
//$continuity->end_date = $this->request->data['end_date'];
$continuity->games = $this->request->data['games'];
debug($this->Continuities->newEntity($this->request->data)->toArray());
debug($continuity);
if ($result = $this->Continuities->save($continuity, ['associated'=>['Games']])) {
$this->Flash->success(__('The continuity has been updated.'));
return $this->redirect(['action' => 'view', $continuity->id]);
}
$this->Flash->error(__('Unable to update the continuity.'));
}
$games = $this->Continuities->Games->getGamesList();
$this->set(compact('continuity', 'games'));
}
And finally the edit.ctp form:
<?= $this->Form->create($continuity) ?>
<fieldset>
<legend><?= __('Edit Continuity') ?></legend>
<?= $this->Form->input('start_date') ?>
<?= $this->Form->input('end_date') ?>
<?= $this->Form->input('games', ['multiple'=>true]) ?>
</fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>
Thanks.
There were a few things that needed to be changed to make this work.
First is the Continuities table:
public function initialize(array $config){
parent::initialize($config);
$this->belongsToMany('Games',
[
'targetForeignKey' => 'game_id',
'foreignKey' => 'continuity_id',
'joinTable' => 'continuities_games',
]);
}
Next, the Games table:
public function initialize(array $config){
parent::initialize($config);
$this->belongsToMany('Continuities',
[
'targetForeignKey' => 'continuity_id',
'foreignKey' => 'game_id',
'joinTable' => 'continuities_games',
]);
}
Now, the ContinuitiesController edit() function:
public function edit($id=null){
$continuity = $this->Continuities->find()->where(['id'=>$id])->contain('Games')->first();
if ($this->request->is(['post', 'put'])) {
$this->Continuities->patchEntity($continuity, $this->request->data(), ['associated'=>['Games']]);
if ($result = $this->Continuities->save($continuity, ['associated'=>['Games']])) {
$this->Flash->success(__('The continuity has been updated.'));
return $this->redirect(['action' => 'view', $continuity->id]);
}
$this->Flash->error(__('Unable to update the continuity.'));
}
$games = $this->Continuities->Games->getGamesList();
$this->set(compact('continuity', 'games'));
}
And finally, the edit.ctp
<?= $this->Form->create($continuity) ?>
<fieldset>
<legend><?= __('Edit Continuity') ?></legend>
<?= $this->Form->input('start_date') ?>
<?= $this->Form->input('end_date') ?>
<?= $this->Form->input('games._ids', ['options' => $games, 'multiple'=>true]) ?>
</fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>