Codeigniter 4 registration to multiple table - codeigniter-4

I have some questions that I do not know how to solve it. Currently I have 2 tables, users and user_profile. I have 2 fields in users_profile, membership and coins which will be added by a default value "yes/no" for membership and "0" for coins.
How do I add "created_by" column from the form username?
How do I add the value in the user_profile table when the user submit the registration form?
This is my code that will store the registration form fields in users table
public function register()
{
$data = [];
helper(['form']);
$validation = \Config\Services::validation();
// To add in is_unique
if($this->request->getMethod() == 'post'){
//validations
$rules = [
'username' => 'required|is_unique[users.username]',
'email' => 'required|valid_email|is_unique[users.email]',
'firstname' => 'required',
'lastname' => 'required',
'dob' => 'required',
'country' => 'required',
'contact' => 'required',
'password' => 'required'
];
$errors = [
'username' => [
'is_unique' => 'Username already exist!'
],
'email' => [
'is_unique' => 'Email already exist!'
]
];
if(!$this->validate($rules, $errors)){
$data['validation'] = $this->validator;
}else{
//store information into database
$model = new AccountModel();
$newData = [
'username' => $this->request->getVar('username'),
'email' => $this->request->getVar('email'),
'firstname' => $this->request->getVar('firstname'),
'lastname' => $this->request->getVar('lastname'),
'dob' => $this->request->getVar('dob'),
'country' => $this->request->getVar('country'),
'contact' => $this->request->getVar('contact'),
'password' => $this->request->getVar('password'),
'created_by' => $this->request->getVar('username')
];
$model->save($newData);
$user_id = $model->insertID();
$newAccount = $model->where('user_id',$user_id)->first();
$userProfileModel = new UserProfileModel();
$newProfile = $userProfileModel->save(['user_id' => $user_id, 'coins' => '0', 'membership' => 'no']);
}
}
echo view('templates/header', $data);
echo view('account/register');
echo view('templates/footer');
}
AccountModel
class AccountModel extends Model{
protected $table = 'users';
protected $allowedFields = [
'username',
'email',
'firstname',
'lastname',
'dob',
'country',
'contact',
'password',
'created_at',
'updated_at',
'created_by'
];
protected $beforeInsert = ['beforeInsert'];
protected $beforeUpdate = ['beforeUpdate'];
protected function beforeInsert(array $data) {
$data = $this->passwordHash($data);
return $data;
}
protected function beforeUpdate(array $data) {
$data = $this->passwordHash($data);
return $data;
}
protected function passwordHash(array $data){
if(isset($data['data']['password']))
$data['data']['password'] = password_hash($data['data']['password'], PASSWORD_DEFAULT);
return $data;
}
}
UserProfileModel
<?php namespace App\Models;
use CodeIgniter\Model;
class UserProfileModel extends Model{
protected $table = 'user_profile';
protected $allowedFields = [
'user_id',
'coins',
'membership'
];
protected $beforeInsert = ['beforeInsert'];
protected $beforeUpdate = ['beforeUpdate'];
protected function beforeInsert(array $data) {
}
protected function beforeUpdate(array $data) {
}
}
?>

How do I add "created_by" column from the form username?
use insertID() ci4 models method aftaer save method executed. It will return the lastest primary key which been saved from the table you want. in this case from your account table
$model->save($newData);
$userId= $model->insertID();
How do I add the value in the user_profile table when the user submit the registration form?
you should have a foreign key in user_profile table that refering to users table primary key
++++++++++++ ++++++++++++++++
+ users + + user_profile +
++++++++++++ ++++++++++++++++
+-id[p.k] + +-id[p.k] +
+-username + +-users_id[f.k]+
+-email + +-coins +
+-email + +-membership +
get lastest user data by $userId, i assume your primary key is 'id' and than save to the user_profile
$newAccount = $model->where('id',$user_id')->first();
$userProfileModel = new UserProfileModel();
$newProfile = $userProfileModel->save(['user_id' => $userId])

Related

sequelize bulkupdate error on column "0" of relation does not exist

With the following migration script:
const rules = [
{ type: 'read', target: 'table1', service: 'admin', scope: 'self', field: 'id' },
{ type: 'read', target: 'table2', service: 'admin', scope: 'self', field: 'id' }
]
module.exports = {
up: (queryInterface, Sequelize) => {
rules.map(({ type, target, service }) => { console.log( type, target, service) })
return queryInterface.bulkUpdate(
'rules',
rules,
{[Sequelize.Op.or]: rules.map(({ type, target, service }) => { console.log( type, target, service); return {type, target, service} })},
).then(ids => {
console.log(ids);
})
},
I am seeing the sql being executed:
Executing (default): UPDATE "rules" SET "0"=$1,"1"=$2 WHERE (("type" = $6 AND "target" = $7 AND "service" = $8) OR ("type" = $9 AND "target" = $10 AND "service" = $11) OR ("type" = $12 AND "target" = $13 AND "service" = $14) OR ("type" = $15 AND "target" = $16 AND "service" = $17) OR ("type" = $18 AND "target" = $19 AND "service" = $20))
Which gives this error:
ERROR: column "0" of relation "rules" does not exist
But how come it makes the index instead of the actual column name.

Yii2 searchmodel related model

As you can see I've gridview (from model called umumiy). And via id_nomi I'm showing nomi.rus (which means rus column from nomi model):
The issue here is I'm trying to make search from Nomi model via umumiy gridview. I'm trying to get values (with nomi.rus) via ajax. This is what I tried:
$model = new UmumiyModel();
$searchModel = new UmumiyModelSearch();
if (Yii::$app->request->isAjax){
$data = Yii::$app->request->post();
$searchModel->nomi->rus = $data['dori_nomi']; // search input value
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->renderPartial('sotish', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
What am I doing wrong???
You can use a public member in NomiSearch model to store text value from "Id Nomi" input field of gridview.
So, in NomiSearch model:
class NomiSearch extends Nomi
{
public $nomiText;
public function rules()
{
return [
// ...
[['nomiText'], 'safe'],
];
}
public function search($params)
{
$query = Nomi::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
]);
if($this->nomiText!=null)
{
$query->andWhere(['IN', 'id_nomi', (new \yii\db\Query())->select('id')->from('nomi')->where(['like', 'nomi', $this->nomiText])]);
}
return $dataProvider;
}
}
Finally, in index view:
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'label' => 'Id Nomi',
'attribute' => 'nomiText',
'value' => function($data) {
return $data->nomi->rus;
},
],

Multiple insertion with addition data with pg-promise

I have a large dataset that I want to insert into a postgres db, I can achieve this using pg-promise like this
function batchUpload (req, res, next) {
var data = req.body.data;
var cs = pgp.helpers.ColumnSet(['firstname', 'lastname', 'email'], { table: 'customer' });
var query = pgp.helpers.insert(data, cs);
db.none(query)
.then(data => {
// success;
})
.catch(error => {
// error;
return next(error);
});
}
The dataset is an array of objects like this:
[
{
firstname : 'Lola',
lastname : 'Solo',
email: 'mail#solo.com',
},
{
firstname : 'hello',
lastname : 'world',
email: 'mail#example.com',
},
{
firstname : 'mami',
lastname : 'water',
email: 'mami#example.com',
}
]
The challenge is I have a column added_at which isn't included in the dataset and cannot be null. How do I add a timestamp for each record insertion to the query.
As per the ColumnConfig syntax:
const col = {
name: 'added_at',
def: () => new Date() // default to the current Date/Time
};
const cs = pgp.helpers.ColumnSet(['firstname', 'lastname', 'email', col], { table: 'customer' });
Alternatively, you can define it in a number of other ways, as ColumnConfig is very flexible.
Example:
const col = {
name: 'added_at',
mod: ':raw', // use raw-text modifier, to inject the string directly
def: 'now()' // use now() for the column
};
or you can use property init to set the value dynamically:
const col = {
name: 'added_at',
mod: ':raw', // use raw-text modifier, to inject the string directly
init: () => {
return 'now()';
}
};
See the ColumnConfig syntax for details.
P.S. I'm the author of pg-promise.

create crud doesnt work in yii2

i make a simple CRUD in yii2 backend from table name "Guru",i already make models with the same table and make the CRUD but when i try to Create new data from the Create function,the data doesnt saved in database at all,i already make the code similar with the frontend and change the namespace but it didnt work at all in backend.
here is my backend "Guru" models code
<?php
namespace backend\models;
use Yii;
class Guru extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'guru';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['nip', 'nama_guru', 'ttl', 'jenis_kelamin', 'alamat', 'telp', 'agama', 'jabatan', 'user', 'pass', 'role', 'tgl_create', 'update_create', 'mapel'], 'required'],
[['jenis_kelamin'], 'string'],
[['mapel'], 'integer'],
[['nip', 'telp', 'jabatan', 'user', 'pass'], 'string', 'max' => 20],
[['nama_guru', 'ttl'], 'string', 'max' => 30],
[['alamat'], 'string', 'max' => 50],
[['agama', 'role', 'tgl_create', 'update_create'], 'string', 'max' => 10]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
//'id_guru' => 'Id Guru',
'nip' => 'NIP',
'nama_guru' => 'Nama Guru',
'ttl' => 'Tempat Tanggal Lahir',
'jenis_kelamin' => 'Jenis Kelamin',
'alamat' => 'Alamat',
'telp' => 'No Telpon',
'agama' => 'Agama',
'jabatan' => 'Jabatan',
'user' => 'User',
'pass' => 'Pass',
'role' => 'Role',
'tgl_create' => 'Tgl Create',
'update_create' => 'Update Create',
'mapel' => 'Mata Pelajaran',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getJadwalGuru() {
return $this->hasMany(Jadwal::className(), ['id_mapel'=>'mapel']);
}
public function getJadwal() {
return $this->hasMany(Jadwal::className(), ['nip'=>'id_guru']);
}
}
and this is my Controller code
namespace backend\controllers;
use Yii;
use backend\models\Guru;
use backend\models\GuruSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
public function actionCreate()
{
$model = new Guru();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id_guru]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
i really dont know why it doesnt work when the other CRUD in backend and frontend is work.i'm new to this framework,please kindly help me.
Could be a validation problem,
you have a lot of required field and if one is missing the model is not saved.
For evaluate this situation try using save(false ) false mean without model validation. in this way :
public function actionCreate()
{
$model = new Guru();
if ($model->load(Yii::$app->request->post()) && $model->save(false)) {
return $this->redirect(['view', 'id' => $model->id_guru]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
If with the param false the model is saved check selectively (by commenting) the rule that create problem with validation.

How to change search model for using one field

I have CRUD generated bu Gii. By default, the search in app use one field for each table column. How should i change my search model, for make search in all columns via alone field?
That's my model:
class UserSearch extends User
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'status', 'created_at', 'updated_at'], 'integer'],
[['username', 'auth_key', 'password_hash', 'password_reset_token', 'email'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = User::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'status' => $this->status,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
$query->andFilterWhere(['like', 'username', $this->username])
->andFilterWhere(['like', 'auth_key', $this->auth_key])
->andFilterWhere(['like', 'password_hash', $this->password_hash])
->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token])
->andFilterWhere(['like', 'email', $this->email]);
return $dataProvider;
}
}
This is how I do it:
public function search($params)
{
..............................
if($this->keyword) {
if(preg_match("/[A-Za-z]+/", $this->keyword) == true) {
$query->andFilterWhere(['like', 'LOWER(CONCAT(name, age, WHATEVERFIELDS)), ', strtolower($this->keyword)]);
} else {
$query->andFilterWhere(['id' => $this->keyword]);
}
}
keyword is not actually a column in the db it is just a variable I attached to the search model. If the keyword is numeric I consider it an ID, you can ignore this part if you want. Otherwise I concat some fields and search in the result. You can also not concat the fields and just add a condition for each field, up to you.
You can see the full file at: https://github.com/Mihai-P/yii2-core/blob/master/models/ContactSearch.php

Resources