What can _time suffix use for laravel database design? - laravel

Most of us are used to the field names like create_time, update_time. Now laravel changed that into created_at, updated_at. Therefore the _time suffix are available for other things.
I, am self, take naming very seriously. And I don't want to waste any good word for naming. What can _time suffix use for laravel database design?

you can override the default laravel created_at and updated_at fields.
class MyModel extends Model
{
const CREATED_AT = 'create_time';
const UPDATED_AT = 'update_time';
}
and also when creating the database instead of using laravel default $table->timestamps(); you can specify the names of the created_at and updated_at columns names as your wish.
$table->timestamp('create_time');
$table->timestamp('update_time');

Related

Alter custom ID column name Laravel 7

We are transforming an old project to Laravel 7
the users table doesn't follow laravel naming
the id column is named "UserId" and the problem it is not auto increment
I already set in the User model
protected $primaryKey = 'UserId';
how can I alter the column to be Auto-Increment, keep in mind it is used in foreign constraints, thank you
If the name of the user table is different, you should specify this naming in the model section. Also, why not change the related column type of the migration process to include auto-increment. To set the auto-increment property, in the model part protected $incrementing = true; You can specify.

Broken Eloquent relationship with extended model

I have a model Asset with documents() { $this->hasMany(Document::class); } through a table data_asset_document. I extend Asset into multiple models, one of which is Equipment. In my seeder for Equipment, I attempt to create a Document bound to the Equipment record:
$asset = Equipment::create([...]);
$document = Document::create([
'name' => "$type Purchase Order",
'tracking_number' => app('incrementer')->current()
]);
$asset->documents()->save($document);
Eloquent produces this query:
update `data_document` set `equipment_id` = 1, `data_document`.`updated_at` = 2019-09-20 14:39:48 where `id` = 1
This is obviously incorrect, since data_document does not have an equipment_id column (Documents "belong to" several models besides Asset). How do I rewrite Asset::documents so that produces the correct mapping, even in its extensions? Or do I need to save my Document through a means other than Asset::documents?
Since your extended asset model is called Equipment, Laravel expects your foreign key to be called equipment_id. You will need to specify the actual foreign key of asset_id in your relationship.
https://laravel.com/docs/6.x/eloquent-relationships#one-to-many
hasMany
documents() {
$this->hasMany(Document::class, 'asset_id');
}
The problem is, I'm not convinced your relationship is really hasMany since you mention what looks like a pivot table data_asset_document as being involved. Many-to-many relationships, like mentioned in your title, would use the belongsToMany method.
https://laravel.com/docs/6.x/eloquent-relationships#many-to-many
https://laravel.com/docs/6.x/eloquent-relationships#has-many-through

Eloquent join with where clause

I have problems to build a relationship with eloquent.
I have two models created, Spielplan and Verein. In model Spielplan I have the fields Team_ID and Spiel_ID. In model Verein I have the field V_ID and Name. Now I need to join this two tables about Team_ID = V_ID.
This is my model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Spielplan extends Model
{
protected $table = 'Spielplan';
public function vereinFunction(){
return $this->hasOne('App\Verein', 'V_ID');
}
}
And this is a function in my web route where I want to get Spiel_ID and Name.
Route::get('test', function(){
$spieleT = App\Spielplan::where('Spiel_ID', '=', 30)->get();
foreach($spieleT as $da){
echo $da->Spiel_ID;
echo $da->vereinFunction->Name;
}
});
The first echo works and I get back Spiel_ID but the second echo gives back ErrorException Trying to get property of non-object.
What is wrong with my code?
Try editing this line:
$spieleT = App\Spielplan::with('vereInFunction')->where('Spiel_ID', '=', 30)->get();.
The with() allows you to fetch the association at the time you use get(). After using get(), you're working with a collection, and can't query the database again.
Try specifying the model primary key as a third argument, because if not, Laravel will assume it is named id, which is not the case.
Allow me to suggest you something: I used to name the tables and fields like you do (in the days I use Codeigniter) but since I started using Laravel around three years ago, I follow Laravel convention (which is recommended, but not imposed). I now name the tables in lowercase, (snakecase) plural, table fields also snakecasm lowercase. Models singular, camelcase similar corresponding table, relation function names as related model, being singular if relation is to one, plural if to many, etc. The advantage of this is among other reflected in model relationship declaration, which is a lot simpler and easier to define.
For instance (only as demonstration of stated above),
tables (with relation one to many:
managers (primarykey: id, name, ......)
technicians (primary key: id, foreingkey: manager_id (related table name in singular plus underscore plus id), name, .....)
models:
Manager:
/* relationships */
public function technicians () // see name as related table, plural due to as many relationship)
{
return $this->hasMany(Technician::class); // as naming convention has followed, you don't need to specify any extra parameters;
}
Techician:
/* relationship */
public function manager() // named as related table, singular due to to one relationship
{
$this->belongsToOne(Manager::class); // again, as naming convention has followed, you don't need to specify any extra parameters;
}
Therefore you can do this:
$manager::find(1);
echo $manager->technicians->first()->name,
or
foreach ($manager->technicians as $technician) {
echo $technician->name;
}
as well as:
$technician->manager->name;
Remember, a proper model relationship definition will save a lot of headache along the way, like the one you have
Hope this help in anyway

Laravel - custom timestamp column names

I am migrating a site from codeigniter to Laravel.
For a legacy table reports, some existing columns created_at and updated_at are named date_created and date_modified respectively.
I wish to tell my eloquent Report model about these custom timestamp column names.
The documentation only provide reference to turning timestamps off or providing custom timestamp formats.
http://laravel.com/docs/eloquent#timestamps
In model your can define constants like this to change the column names
class BaseModel extends Eloquent {
const CREATED_AT = 'date_created';
const UPDATED_AT = 'date_modified';
}
or use you can use something like this Managing Timestamps

updated_at timestamp not being updated when using sync in Laravel 4

I use the following code to update tags and other information about an organization:
Route::put('org/{org}', function(Org $org){
$org->description = Input::get('description');
$org->website = Input::get('website');
$org->save();
$org->tags()->sync(Input::get('tags'));
return Redirect::to('org/'.$org->id)
->with('message', 'Seccessfully updated page!');
});
However, if I only change the tags associated with this org, the updated_at field is not updated. I added protected $touches = array('org'); to my Tag model, but this only seems to work for belongsTo relations, while the relation between orgs and tags is a many-to-many polymorphic relation.
Is there a way to allow the sync function to automatically update the default updated_at timestamp?
Doing it manually, like below, will update the timestamp even if my edit doesn't actually change anything:
$org->updated_at = \Carbon\Carbon::now()->toDateTimeString();
$org->save();
You have to setup touches array on Tag model, BUT it has limitation:
Eloquent guesses the relation name, so will work only if the name complies with the convention.
Organization model -> organizations relation.
And if you want to manually update the timestamp you can use this instead:
$model->touch();

Resources