I have a one to many relationship which is using a pivot table to attach related models.
The standard timestamps are working correctly and the created_at / updated_at are getting populated with the dates when the relationshi gets created or modified.
However, I have a case where I would like to override the timestamps values.
I would like to do something like this :
$user->tickets()->attach($ticket->id)
->withTimestamps(['created_at' => '2021-01-01 00:00:01','updated_at' => '2021-01-01 00:00:01']);
Can anyone please help ?
As confirmed by #N69S, the correct syntax to include or override column values during attach is to pass an associative array of nested columns:
$user->tickets()->attach([
$ticket->id => [
'created_at' => '2021-01-01 00:00:01',
'updated_at' => '2021-01-01 00:00:01'
]
]);
This should add a record to your pivot table with the correct User ID, Ticket ID and overridden timestamps.
Related
I add test records to the database using seeds
public function run()
{
DB::table('categories')->insert([
['id' => 1,'name' => 'Select a category', 'slug' => null],
['id' => 2,'name' => 'Computers', 'slug' => 'computer-&-office'],
]);
}
But then, if I want to add a new record to the database, already through the form, I get the error
SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "categories_pkey"
I understand that when I add a new record through the form, it is created with id = 1, and I already have this id in the database. How can I avoid this error?
You should remove id from insert() and make it auto increment in mysql,
It complains about a unique constraint, meaning your primary key is indexed as "categories_pkey" or you have another field that is unique.
This happens because you are inserting a record and a record already exists where that column must be unique.
In general production workflow, when you add a record you never specify an ID. Most cases (there are exceptions) ID is an autoincrement integer, meaning it adds up automatically. On the first insert the database set its ID to 1, the second to 2 and so on.
As a seeder, its generally a good idea to set up the ID so you know that a certain ID matches a certain item (as a base content of a project like user states or roles).
As a regular workflow (from a form submission), you can have something like this
DB::table('categories')->insert([
['name' => 'some value', 'slug' => 'some slug']
]);
However, I don't advise to use DB::table when Laravel provides ActiveRecords pattern (ORM, called Eloquent) which you should take a look here.
https://laravel.com/docs/8.x/eloquent#introduction
Besides the benefits of layer abstraction and working with activerecords, It produces a much cleaner code like
$data = ['slug' => 'some slug', 'name' => 'some name'];
Category::create($data);
I've been pulling my hair for hours now trying to find the problem with this lines of code:
ContentSetting::updateOrCreate(
['content_id' => $this->id, 'key' => 'max_width'],
['value' => $value]
);
It is supposed to check if there is a row in my content_settings table with a certain content id and the key "max_width" and if so update it and if not create it. It's used in a model mutator, hence the $this.
Anyway, no matter what values I try to put in, this ALWAYS results in this mysql query being executed (only with different time stamps):
insert into `content_settings` (`content_id`, `updated_at`, `created_at`) values (2, '2020-10-15 14:07:00', '2020-10-15 14:07:00')
...simply making new rows with empty key and value. Can anyone please spot the error? Or is this a bug somewhere? Something with "key" being a reserved word?
you should set the fields you want to use in mass assignment in the $fillable array in your model:
class ContentSetting extends Model
{
protected $fillable = ['content_id','key','value'];
}
So I'm trying to attach id's with some meta data to a pivot table in Laravel 5.
For some reason, I get the two inserts where there should be one, and the wrong ID's being inserted the second time round.
I'm not sure if there is something I might be missing here.
This is the code:
$match_values = array(
'dataId' => $result->id,
'dataMetaId' => $the_meta->id
);
$result->campaignDataMeta()->attach($match_values, [
'meta_value' => $value
]);
The database structure consists of a main campaignData table for email campaigns, a campaignDataMeta table (id, timestamps, name) for email meta data names, and a lookup table campaignDataMatches (id, campaignDataId, campaignDataMetaId, meta_value).
In campaignDataMatches I get the campaignDataId value sometimes being inserted into the campaignDataMeta column.
I've solved the problem.
Apparently had to add the relevant ID (in this case the dataMetaId) within the attach parameter.
Like this:
$result->dataMeta()->attach([$data_meta_id => [
'meta_value' => $value
]]);
Check the database columns primary maybe the dataId and metaId are both primary.
Please could anyone explain to me a difference between [attributes:protected] array and [original:protected] array in laravel when using print_r to an array?
When Model reads data from table, arrays 'original' and 'attribute' contains same data. When you change the attribute value (ex $user->name='John'), the change is reflected only on the 'attributes' array but 'original' remains same. (hence the name).
When update() on a model is called, method checks what has changed comparing two arrays and construct query only for changed fields. Thus, in the case of $users->name change Laravel will not create this code:
UPDATE users set name = 'John', password = 'pass', email = 'email' where id = 1
but this:
UPDATE users set name = 'John' where id = 1
This may not be the only way Eloquent uses 'original' array. I found clockwork helpful when you need to see what's going on under the hood of Eloquent.
I am trying to validate an email field so that I make sure it's unique, but not in a row with a certain id, which I do like so:
'email' => 'required|email|unique:seller_user,email,'.$seller_id,
That works, but it automatically searches for a column named id, whereas in my table that column is actually called seller_id, so how can I change that?
You can specify the field to search using the fourth parameter to the rule:
'email' => 'required|email|unique:seller_user,email,'.$seller_id.',seller_id',