How to get auto increment id after save in Yii2 - yii2

Im trying to get auto increment id after save in Yii2.I tried to the following code block but its not working.
public function actionAddgroup()
{
$model = new Groups();
$model->groupName=Yii::$app->request->post('groupName');
$model->save(); // a new row is inserted into user table
return $model->id;
}

Where you are trying to return the $model->id immediately after creating a new Groups instance, the $model variable may still only have the data you put into it.
To get data added at the database level, you may need to call $model->refresh() in order for it to refresh the data in your local $model variable with the current data from the database.
In other words, try this:
public function actionAddgroup()
{
$model = new Groups();
$model->groupName=Yii::$app->request->post('groupName');
$model->save();
$model->refresh();
return $model->id;
}

public function actionAddgroup()
{
$model = new Groups();
$model->groupName=Yii::$app->request->post('groupName');
$model->save(); // a new row is inserted into user table
return $model->getPrimaryKey();
}

Related

Laravel Model get next increment ID when the Table linked with Model is Non-AutoIncrement

As I mentioned in Question, the current Laravel 6.0 project I am working on has bit weird DB setup, where the Model's(the MainModel here) MySQL table has been set with AutoIncrement as NULL. And client won't allow to change the Table's definition at all.
I want to reliably find the next and previous IDs of the Model(since I can't find from table as AutoIncrement is set to NULL) before inserting record, so that I can make an entry of relevant record(for eg. image(s) of a testimonial/faq or any WYSIWYG content field) into another referential table first, by correctly inserting the main Model's ID into the refrential ID field of that another table.
Currently I have this in my main Model, but the next method doesn't reliably return the exact incremented ID consistently:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Te7aHoudini\LaravelTrix\Traits\HasTrixRichText;
class [MainModel] extends Model
{
use HasTrixRichText;
protected $guarded = [];
public $timestamps = false;
protected $primaryKey = 'id';
protected $connection = '[connection1]';
protected $table = '[main_table]';
protected $fillable = ['id', '[titlefield]', '[wysiwyg_field]'];
/**
* Setup model event hooks
*/
public static function boot()
{
parent::boot();
self::creating(function ($model) {
$model->id = $model->max('id') + 1;
});
}
/**
* Get next available Faq Id
*/
public function next()
{
return ++$this->id;
}
}
Any help is appreciated...
As I understand you are confused about how to call statically model queries. You can achieve the same logic by using a static self-reference static.
public static function next()
{
return static::max('id') + 1;
}
This would be equivalent to.
MainModel::max('id');
Bonus to make it a transaction to avoid id clashing. This can lock the database in fun ways, but will avoid you have the same ids, something similar to this, very simple example.
DB::transaction(function () {
$id= MainModel::next();
$newModel = MainModel::create(['id' => $id]);
});
As I understanding, in order to get the next increment id, you need to call the following line.
Model::lastest()->first()

Laravel - Update dynamic form fields in database

I have a dynamic form where the user should be able to add or remove fields while editing.
I am able to update the exact number fields that are in the database table. But what I want is if a user clicked a 'Delete Subject' and 'Update' buttons, I want that entire row deleted from the database.
And, if he added a subject by clicking 'Add another Subject' the form and clicked 'Update' I want those subjects added. What am I missing here?
Note: I built a One-to-Many relation between New and Subjects, where a New has many subjects and many subjects belong to a New (It works fine).
My form looks like this
New Model
protected $fillable = ['name', 'address'];
public function subjects() {
return $this->hasMany(Subjects::class, 'new_id');
}
Subjects Model
protected $fillable = ['new_id', 'sub_code', 'sub_name', 'sub_img'];
public function subs(){
return $this->belongsTo(New::class, 'new_id');
}
Create Method
public function create(Request $request, New $new){
$new = New::FindorFail($id)
$subjects= [];
$sub_images = $request->file('sub_img');
$sub_name = $request->sub_name;
for ($i=0; $i < count(request('sub_code')); ++$i)
{
$subjects = new Subjects;
$subjecs->sub_code = request('sub_code')[$i];
$subjects->sub_name = request('sub_name')[$i];
$sub_img_name = uniqid() . '.' . $sub_images[$i]->getClientOriginalExtension();
$sub_images[$i]->move(public_path('/images/'), $sub_img_name);
$subjects->sub_img = '/images/'.$sub_img_name;
$new->subjects()->save($subjects);
}
}
Update Method
public function update(Request $request, $id){
$new=New::FindOrFail($id)
$subjects = Subjects::with(['subs'])->where('new_id', $new->id)->get();
$new->update($request->all());
$i=0;
foreach( $subjects as $new_subjects)
{
$sub_images =request()->file('sub_img');
$sub_name = request('sub_name');
if(isset($sub_images[$i]))
{
$pathToStore = public_path('images');
if($request->hasFile('sub_img') && isset($sub_images[$i]))
{
$sub_img_name = uniqid() . '.' . $sub_images[$i]->getClientOriginalExtension();
$sub_images[$i]->move(public_path('/images/'), $sub_img_name);
$new_subjects->sub_img = '/images/'.$sub_img_name;
$new_subjects->sub_code = request('sub_code')[$i];
$new_subjects->sub_name = request('sub_name')[$i];
$new_subjects->sub_img = "images/{$sub_img_name}";
$i++;
$new->subjects()->save($new_subjects);
}
}
}
}
Subjects Database
I want this table row be updated (added or deleted) after user edit the form.
From my experience with Laravel, I think the problem is that you call the Product model instead of the New model so maybe you need to fix it.
you reference the New model :
public function subs(){
enter code herereturn $this->belongsTo(New::class, 'new_id');
}
then you use the wrong model Product :
$new=Product::FinOrFail($id)
Another thing is to double check the fillable attribute within the Subject model also you can write the update action and do something like

Yii2 pass query result to a action in another controller

I'm trying to insert record into my audit table upon update of record in any other table. For example, if a user update his profile I want to store the old record and the newly updated record in my audit table. For this in my user model I'm trying to use beforeSave() and pass the value to my audit controller
public function beforeSave($insert)
{
if((parent::beforeSave($insert))){
// Place your custom code here
$query = DepCustomer::findOne($this->customer_id);
Yii::$app->runAction('audit-trial/createaudit', ['query' => $query]);
return true;
}
}
And the action code in audit controller for now
public function actionCreateaudit($query)
{
$model = new Audit();
$model->old = '';
foreach($query as $name => $value){
//$temp = $name .': '. $value.', ';
//$contentBefore[] = $temp;
$audit->old = $audit->old.$name .': '. $value. ', ';
}
// I've not yet any other code for now I'm trying to get the old value
$model->save();
}
I'm getting 404 not found error. What do I need to change in my code to make it work? Thank you!
instead of runAction() . If you want to perform operation on another model, prefer to create a static function in that model (in your case Audit model) to save the data
public function beforeSave($insert)
{
if((parent::beforeSave($insert))){
// Place your custom code here
$query = DepCustomer::findOne($this->customer_id);
Audit::saveOldDetails($query);
return true;
}
}
and write saveOldDetails function in Audit Model
public static saveOldDetails($query){
// your business logic here
}
Refer this link
http://www.yiiframework.com/doc-2.0/yii-base-controller.html#runAction()-detail

Yii2 - How to user multiple table (model) in a single form

I need to use multiple table in a single form, on form submitted the data will save in multiple tables in the data base, also wants to perform validation and update.
I suggested snippet of code, at beginning of controller class define
private $_rel = null;
controller action ,
public function actionSaveUser(){
if (!empty($_POST['Contact'])){
$model = new Contact;
$model->attributes = $_POST['Contact'];
if ($model->save()){
$this->_rel = new Address;
$this->_rel->attributes = $_POST['Contact'];
if ($this->_rel->save()){
$this->render('view_name');
} else{
throw new CHttpException(404, 'Something went wrong message..');
}
}
}
}
I hope this code help you.

Getting the last User ID in Zend Framework

Using MySQL query browser, I manually made a table called users and input some date in the fields. I set the primary key to id and set it to auto increment. There are 3 rows, the highest id is 3.
I then made the following class in the method directory to call upon the data in the table etc.
class Application_Model_DbTable_User extends Zend_Db_Table_Abstract
{
protected $_name = 'user';
public function getLatestUserId()
{
$id = $this->getAdapter()->lastInsertId();
return $id;
}
}
In the controller I do the following which gets the value generated by the method and lets the view access it:
$usersDbModel = new Application_Model_DbTable_User();
$lastUserId = $usersDbModel->getLatestUserId();
$this->view->lastUserId = $lastUserId;
In the view I then echo it to display it to the user:
echo $this->lastUserId;
However, even though my last id in the users table is 3. It displays 0.
I have also tried:
public function getLatestUserId()
{
$sql = 'SELECT max(id) FROM user';
$query = $this->query($sql);
$result = $query->fetchAll();
return $result;
}
But this just throws out a server error.
What have I done wrong?
Am I missing something?
Is there another way of doing this?
The answer was:
$sql = 'SELECT max(id) FROM user';
$query = $this->getAdapter()->query($sql);
$result = $query->fetchAll();
return $result[0]['max(id)'];
If you queried like "SELECT id FROM USERS SORT BY id DESC LIMIT 0,1"
You would get nothing but the id of the newest user, no?
if you use a select statement like
SELECT max(id) FROM USERS;
If you haven't tried having a function in the controller try something like this.
class IndexController extends Zend_Controller_Action {
public function init() {
}
public function indexAction() {
}
public function getLatestUserId()
{
$bootstrap = $this->getInvokeArg('bootstrap');
$resource = $bootstrap->getPluginResource('db');
$db = $resource->getDbAdapter();
$sqlrequest = "select max(id) as Idmax from user";
$rows = $db->fetchAll($sqlrequest);
foreach ($rows as $row)
echo $maxId = $row['Idmax'];
return $maxId;
}
}
and your bootstrap file would look something like
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initConfig()
{
$config = new Zend_Config($this->getOptions());
Zend_Registry::set('config', $config);
return $config;
}
}
Hopefully something like that works, hope it helped
The problem is that Mysql doesn't really support lastInsertId() it will in some cases return the last id of an auto incrementing primary key.
Several solutions have been presented here and most will return the last id of the primary key, which may or may not be what you really need.
This method will also do the same using the select() object.
public function getlastInsertId(){
$select = $this->select();
$select->from($this->_name, "id");
$select->order('id DESC');
$select->limit(0, 1);
$result = $this->fetchAll($select)->current();
return $result->id;
}
I think that over time you may find these kinds of methods unreliable if what you're really after is the last id you inserted. Over time as records are added and deleted the database may or may not fill in vacant id's depending on which database you are currently using and how that database is set up.
In most cases we need the id of the last item inserted very soon after inserting it, usually to update a view script. In this instance I usually just make the whole row object part of the return.
Here is an example of what I mean:
/**this method will save or update a record depending on data present in the array*/
public function saveUser(array $data) {
/**cast data array as std object for convience*/
$dataObject = (object) $data;
/**if id exists as array and has a non null value*/
if (array_key_exists('id', $data) && isset($data['id'])) {
/**find row if updating*/
$row = $this->find($dataObject->id)->current();
} else {
/**create new row*/
$row = $this->createRow();
}
$row->first_name = $dataObject->first_name;
$row->last_name = $dataObject->last_name;
$row->email = $dataObject->email;
/**save or update row*/
$row->save();
/**return the $row you just built or you can return $result = $row->save(); and get*/
/** just the primary key. Save() will throw an exception if table is marked read only*/
return $row;
}