Model::insert() is not updating timestamps - mysql

I added the timestamps in the Migration(Schema) and the model
$table->timestamps(); //In the Schema
public $timestamps = true; //In the model
I made an array with all fields of the database and inserted into the database.
Checkin::insert($input);
In the table, it updates all the fields except the updated_at, created_at timestamps
I have another(default) model for Users and it updates the timestamps. In that model, I am using the ->save() method

Instead of insert, you should use create if you want the timestamps to be set:
Checkin::create($input);
You can also do
$checking = Checkin::create($input);
which will give you the just created checkin.
Make sure the fields are fillable by adding this to your model:
protected $fillable = array(
'name',
'field_1',
'field_2',
... // all the fields you want to be mass-assignable here
);
Also, there's no need to set public $timestamps = true; as that is the default in Laravel if you're using Eloquent models.

Related

database relation between two different server

I have two servers and both of them contain several tables. Many of them contain relations. Now I need to join those tables and fetch data. I have no clue how to write this sort of query. Currently, I'm working in Laravel. Any suggestions will help me.
Thanks in advance.
If you want to use model relationships you can add connection and table field in your model;
class User extends Model {
public $connection = 'firstconnection';
public $table = 'users';
...
public function comments() {
return $this->hasMany(Comment::class);
}
}
class Comment extends Model {
public $connection = 'secondconnection';
public $table = 'comments';
...
}
You can define connections in your config/database.php, default connection is mysql.
If you write raw queries you can use full table path (specify database):
SELECT * FROM db1.users JOIN db2.comments ON db1.users.id = db2.comments.user_id;
Note: you must have enough privileges on both tables to join and select data. If you use exists, has or semething like that where ORM needs to join two table.
Hope this helps you

Laravel 6 - Updating the model timestamps

After some actions inside of my Laravel 6 app, I'm trying to update my model object $last (class CurrentConditions). As you can see below, I'm trying to update update_time property to current timestamp. Except this property, I have another timestamp property inside the CurrentConditions model: external_update_time and I want this property to stay the same after updating and saving $last object. Problem is that external_update_time property is updated to current time after saving the model.
/** #var CurrentConditions $last */
$last = $this->getLastUpdatedCurrentConditions($cityID);
$last->update_time = Carbon::now("UTC");
$last->save();
Here is my model:
class CurrentConditions extends Model
{
protected $table = 'current_conditions';
...
public $timestamps = false;
protected $dates = ['update_time', 'external_update_time'];
...
}
And here is my migration code:
Schema::create("current_conditions", function (Blueprint $table) {
$table->bigIncrements("current_conditions_id");
...
$table->timestamp("external_update_time");
$table->timestamp("update_time")->useCurrent();
});
So why is external_update_time updating as well? Thanks for any help.
Please check that external_update_time is not set on Update to set CurrentTimeStamp
in the schema table design
This is how MySQL 5.7 works - first timestamp will be updated with current timestamp. You should modify order of columns in your migration (assuming it's not deployed yet to live server) to achieve what you want:
$table->timestamp("update_time")->useCurrent();
$table->timestamp("external_update_time");

Laravel Schema Default Value Function

I want the default value for my Server model's sid to be the uniqid() function to be run every time. Something like this, for example
$table->string('sid')->default(uniqid);
How can I achieve this result?
You can use an event listener to set the sid attribute on your model. You can do this using an event listener, model observer, or just a closure function inside your model's boot function.
// app\Models\YourModel.php
/**
* Define model event callbacks.
*
* #return void
*/
public static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->sid = uniqid();
});
}
Unfortunately no, MySQL requires constants for the default. So, the default value must be a constant, it cannot be a function or an expression.
Only way is to allow the fields nullable and add uniqid() while creating records on the database like this:
$table->string('sid')->nullable();
Now, When you add records set sid value to uinqid() value
If you have model named Table then
$record = new Table();
$record-> -----
--------
--------
$record->sid = uniqid();
$record->save();
This is the way you can achieve.
UPDATE
You can set default value in model as well like this:
protected $attributes = array(
'sid' => uniqid(),
);
Hope you understand.
i think this is the easiest way
$table->unique('sid')->index()

Insert a field with value whenever new instance of modal is created

I want to insert a field with value whenever new row is created for a modal.
Ex: Suppose this is my user.php modal
class User extends Authenticatable
{
protected $guarded = ['id'];
}
What i want is in my application anywhere when i insert a row in user table, then i want to insert an extra column code with its value in user table.
Ex: If i do below in my application
User::create(['name'=>'xyz', 'password' => 'kajsndjk']);
then it should insert an extra column code =>'Qwedf' also in my table.
In my application there are many places where i am creating the users, so i don't want to remember every time to insert code column.
Please suggest how can i achieve it.
Overriding the static create function on the User class is the only thing that will work in my opinion.
public static function create(array $attributes = [])
{
$object = parent::create($attributes);
$object->code = 'some text';
$object->save();
return $object;
}
I've tested and like I expected, oseintow's answer will not work, because it would work only if you directly modified code variable, which you obviously are not doing.
Add this mutator to your User model
public function setCodeAttribute($value)
{
$this->attributes['code'] = "Qwedf";
}
Anytime you are saving a record code will be assigned the Qwedf value

Yii model: Dynamic table relations

Table.linkedIndex is related to LinkedIndex.ID. The value of the field LinkedIndex.TableName is either Linked1 or Linked2 and defines which of these tables is related to a row in Table.
Now i want to make a dynamical link with Yii models so that i can easily get from a Table row to the corresponding Linked1 or Linked2 row:
Table.linkedID = [LinkedIndex.TableName].ID
Example
Table values:
LinkedIndex values:
Now I should get the row from Linked2 where ID=2:
$model = Table::model()->findByPk(0);
$row = $model->linked;
Model
In the model Table, I tried to make the relation to the table with the name of the value of linkedIndex.TableName:
public function relations()
{
return array(
'linkedIndex' => array(self::HAS_ONE, 'LinkedIndex', array('ID' => 'linkedIndex')),
'linked' => array(
self::HAS_ONE,
'linkedIndex.TableName',
array('ID' => 'linkedID'),
)
)
}
But then I get the error:
include(linkedIndex.TableName.php) [function.include]: failed to open stream: No such file or directory
Is there any way to make a dynamic relation Table.linkedID -> [LinkedIndex.TableName].ID with Yii Models?
Per the Yii docs here:
http://www.yiiframework.com/doc/api/1.1/CActiveRecord#relations-detail
I'd suggest using self::HAS_ONE instead (unless there can be multiple rows in LinkedIndex with the same ID - although from the looks of above, I doubt that's the case).
You can link tables together that have different keys by following the schema:
foreign_key => primary_key
In case you need to specify custom PK->FK association you can define it as array('fk'=>'pk'). For composite keys it will be array('fk_c1'=>'pk_с1','fk_c2'=>'pk_c2').
so in your case:
public function relations(){
return array(
'linkedIndex' => array(self::HAS_ONE, 'LinkedIndex', array('ID' => 'linkedIndex')),
);
}
where LinkedIndex is the class name for the LinkedIndex model (relative to your Table model - i.e. same folder. You could change that, of course) and array('ID' => 'linkedIndex') specifies the relationship as LinkedIndex.ID = Table.linkedIndex.
Edit
Looking at your updated example, I think you're misunderstanding how the relations function works. You're getting the error
include(linkedIndex.TableName.php) [function.include]: failed to open stream: No such file or directory
because you're trying to create another relation here:
'linked' => array(
self::BELONGS_TO,
'linkedIndex.TableName',
array('ID' => 'linkedID'),
)
This part: linkedIndex.TableName refers to a new model class linkedIndex.TableName, so Yii attempts to load that class' file linkedIndex.TableName.php and throws an error since it doesn't exist.
I think what you're looking for is to be able to access the value TableName within the table LinkedIndex, correct? If so, that's accessible from within the Table model via:
$this->linkedIndex->TableName
This is made possible by the relation we set up above. $this refers to the Table model, linkedIndex refers to the LinkedIndex relation we made above, and TableName is an attribute of that LinkedIndex model.
Edit 2
Per your comments, it looks like you're trying to make a more complex relationship. I'll be honest that this isn't really the way you should be using linking tables (ideally you should have a linking table between two tables, not a linking table that says which 3rd table to link to) but I'll try and answer your question as best as possible within Yii.
Ideally, this relationship should be made from within the LinkedIndex model, since that's where the relationship lies.
Since you're using the table name as the linking factor, you'll need to create a way to dynamically pass in the table you want to use after the record is found.
You can use the LinkedIndex model's afterFind function to create the secondary link after the model is created within Yii, and instantiate the new linked model there.
Something like this for your LinkedIndex model:
class LinkedIndex extends CActiveRecord{
public $linked;
public static function model($className = __CLASS__){
return parent::model($className);
}
public function tableName(){
return 'LinkedIndex';
}
public function afterFind(){
$this->linked = new Linked($this->TableName);
parent::afterFind();
}
//...etc.
}
The afterFind instantiates a new Linked model, and passes in the table name to use. That allows us to do something like this from within the Linked model:
class Linked extends CActiveRecord{
private $table_name;
public function __construct($table_name){
$this->table_name = $table_name;
}
public static function model($className = __CLASS__){
return parent::model($className);
}
public function tableName(){
return $this->table_name;
}
//...etc.
}
which is how we dynamically create a class with interchangeable table names. Of course, this fails of the classes need to have separate operations done per-method, but you could check what the table_name is and act accordingly (that's pretty janky, but would work).
All of this would result in being to access a property of the linked table via (from within the Table model):
$this->linkedIndex->linked->foo;
Because the value of LinkedIndex.TableName and Table.linkedID is needed to get the values, I moved the afterFind, suggested by M Sost, directly into the Table-Class and changed its content accordingly. No more need for a virtual model.
class Table extends CActiveRecord {
public $linked; // Needs to be public, to be accessible
// ...etc.
public function afterFind() {
$model = new $this->linkedIndex->TableName;
$this->linked = $model::model()->findByPk( $this->linkedID );
parent::afterFind();
}
// ...
}
Now I get the row from Linked2 where ID=2:
$model = Table::model()->findByPk(0);
$row = $model->linked;