How to write a NotMapped entity in Laravel Model? - php

I am novice in laravel, therefor my question may be odd to someone. Well, my question is how can I write a entity in Laravel Model class which will not be created any field in database after my migration. For example
class JobseekerModel extends Model
{
use SoftDeletes;
protected $table='dbl_jobseekers';
protected $primaryKey='id';
protected $fillable=[
'FirstName',
'MiddleName',
'LastName',
'Dob',
'Education',
'DesireField',
'Skill',
'SpecialSkill',
'Experience',
'Location',
'HomeAddress',
'Salary',
'Comenteries',
'Resume'
];
protected $dates = ['deleted_at'];
}
This is my Model, now I want to add another property named 'PagedListSize' in my Model, however I don't like to create it as a database column. So how do I do this?
For example I am acquainted to use NotMapped property in .Net Framework, which is written like
[NotMapped]
public int PagedListSize {set; get;}
So, how do I able to do this. Is there any way to do this in laravel? i am working on Laravel 5.4

You can create custom Mutators to have that kind of custom properties wihout mapping them to database fields in Laravel.
class Tag extends Model
{
public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
public function setFullNameAttribute($value)
{
list($this->first_name, $this->last_name) = explode(' ', $value);
}
}
and then you can use it like this after you initialize the model:
$tag->full_name = "Christos Lytras";
echo $tag->first_name; // prints "Christos"
echo $tag->last_name; // prints "Lytras"
Here is a tinker screenshot:

The best way to do this in Laravel indeed is through custom Mutators. In addition, mutators can be configured to be displayed in the json or array output dump of the model. e.g. for PagedListSize we could have:
public functionGetPagedListSizeAttribute()
{
return #some evaluation;
}
protected $appends = array('pagedListSize');
This way, pagedListSize will not only be available directly as a field but also be available whenever the model is serialized as Json or Array.

You can add protected properties to Laravel Model, it's fine as long as they do not collide with field-names. Besides, with Laravel, migration are deciding of DB structures, not models, so you do not take the risk to create fields automatically (actually, default models works with no properties out of the box).
EDIT : Example from the default package User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* You can add some properties here
* will require getter and/or setters
* does not need to be fillable
*/
protected $someLogicalProperty;
}
The actual db structure is defined in the migration (2014_10_12_000000_create_users_table.php) :
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
As you can see, timestamps and token are not even listed in the user model. All the fillable when defined will be setable as public property on the user object ($user->name = 'Bob';, but you can also pass it as argument to the create()/save() inherited methods). Entities are not directly accessed in Laravel, but there are here and can be further specified if needed.

Related

Laravel model create() and fill() methods doesn't work

I have the following model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Review extends Model
{
protected $fillable = ['*'];
public $dates = ['page_available_untill'];
public static function findByUUID(string $uuid): self|null
{
return self::where('page_uuid', $uuid)->get()->first();
}
}
Model seeder:
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
public function run()
{
Review::create([
'page_uuid' => ReviewUUIDGenerator::generate(),
'order_id' => 10000
]);
}
}
Migration:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateReviewsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('reviews', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->integer('order_id');
$table->string('page_uuid');
$table->dateTime('page_available_untill')->nullable();
$table->integer('operator_speed')->nullable();
$table->integer('operator_quality')->nullable();
$table->integer('operator_politeness')->nullable();
$table->integer('master_arrival_speed')->nullable();
$table->integer('master_work_quality')->nullable();
$table->integer('master_politeness')->nullable();
$table->enum('materials_quality', ['Хорошее', 'Плохое', 'Не устанавливали'])->nullable();
$table->enum('would_recommend', ['Да', 'Нет', 'Затрудняюсь ответить'])->nullable();
$table->double('payment_summ', 9, 2)->nullable();
$table->text('comment')->nullable();
$table->json('photos')->default(json_encode([]));
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('reviews');
}
}
Basically the model stores a review info for a given job (let's say for example my job is to help people make some documents and after my job is done i ask my clients to submit a review to my job)
The problem is:
when i set $fillable = ['*']; i can access model attributes like an object properties, BUT i cant create a new model or fill model with some model attributes if i don't hard code needed properties to $fillable like $fillable = ['page_available_untill', 'order_id', 'etc'] is that how it acually works or i don't understand something?
protected $guarded = [];
Replace protected $fillable = ['*']; by protected $guarded = [];
protected $fillable = ['*'];
this please enter column name in fillable, for example
protected $fillable = ['page_uuid','order_id'];
Add column name in fillable and let me know if its working or not
In eloquent ORM, $fillable attribute is an array containing all those fields of table which can be filled using mass-assignment.
Mass assignment refers to sending an array to the model to directly create a new record in Database.
Refer this
https://laravel.com/docs/9.x/eloquent#mass-assignment
You can't use * in fillable method. You have to add all needed column in the fillable.

Laravel MongoDB associated model not setting foreign id

I've set up a Laravel 9 & PHP 8 project and am using Mongo DB community version 5.0 as my NoSQL database. I've installed the jenssegers/laravel-mongodb package and have connected it to my MongoDB server.
I'm using MongoDB for the benefit of not having to define a schema for my migrations as such.
I've set up two models:
Application hasOne - application
ApplicationPayday - belongsTo application
Application model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Jenssegers\Mongodb\Eloquent\Model;
class Application extends Model
{
use HasFactory;
/**
* The collection associated with the model.
*
* #var string
*/
protected $collection = 'applications';
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [
'id',
'created_at',
'updated_at'
];
/*
** Linked application payday
*/
public function payday()
{
return $this->hasOne(ApplicationPayday::class);
}
}
ApplicationPayday model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Jenssegers\Mongodb\Eloquent\Model;
class ApplicationPayday extends Model
{
use HasFactory;
/**
* The collection associated with the model.
*
* #var string
*/
protected $collection = 'application_paydays';
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [
'id',
'application_id',
'created_at',
'updated_at'
];
/*
** Linked application
*/
public function application()
{
return $this->belongsTo(Application::class);
}
}
I have created two migrations for each of these models, with basic details, the rest of my data is saved without defining a specific migration which is what I need, however, since a ApplicationPayday is linked to an Application, I've created a foreginId field for this.
My migrations look like the following:
applications
Schema::create('applications', function (Blueprint $collection) {
$collection->id();
$collection->timestamps();
});
application_paydays
Schema::create('applications', function (Blueprint $collection) {
$collection->id();
$collection->foreignId('application_id');
$collection->timestamps();
});
Now, when I save my data, I want to automatically save associated models and link them together automatically by the fields, I tried this Stackoverflow, it's creating my data, but I don't see my application_id field in my ApplicationPayday model, why?
I cannot move it out of my $guarded array as the dat being saved is from a legacy system already containing the field, so of course, it wouldn't match up with the ids in MongoDB.
What am I missing from below:
// source data
$source = $request->input('application');
// create the application
$application = Application::create($source['Application']);
// payday application
$payday = ApplicationPayday::create($source['ApplicationPayday']);
$payday->application()->associate($application);

Laravel MongoDB cannot get belongsTo relationship properly value

When using jenssegers/laravel-mongodb, the belongsTo relationship properly always returns null, despite, when dumping, the value appearing. How can I get the belongsTo relationship?
I have two models, a post and a user. Where the post has a belongs to relationship with user. When I use $post->user, I always get null. Despite the fact that when dumping ($post) it clearly shows the user id!
User (Using the boiler plate laravel auth, except with MongoDB auth user)
use Jenssegers\Mongodb\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $collection = 'users';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Post:
use Jenssegers\Mongodb\Eloquent\Model;
class Post extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
Based on the Jessenger's readme doc, this is fairly standard and nothing special.
Post::all()->first() related values dump
#attributes
"_id" => MongoDB\BSON\ObjectId {#1601 ▶}
"user" => "602f054f6294a33233745fab"
I saved the user using this, just getting the logged in user's ID.
$post->user = auth()->user()->getAuthIdentifier();
However, getting $post->user always returns null
$post = Post::all();
dd($post->user) // null
$post->user() works and returns the relationship, with the related value being the actual user.
Other posts suggested setting the foreign and local key
Post Class
public function user()
{
return $this->belongsTo(User::class, 'user_id', '_id');
}
This doesn't work either.
Initially I saved the user as an ObjectId, but that doesn't work either.
My current idea is to just scrap the belongsTo functions entirely and just set the related IDs manually. The issue is that now I'll need to manually query for the user instead of the package doing so for me, or using Post::with('user') to autoload it.
How can I get the belongsTo relationship ID value?
PHP: 8.0.2
Laravel Framework: 8.28.1
Jessengers/MongoDB: 3.8.2
I have found a bizarre work around, add user_id to the fillable field and fill that out
use Jenssegers\Mongodb\Eloquent\Model;
class Post extends Model
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'user_id'
];
public function user()
{
return $this->belongsTo(User::class);
}
}
EG
Controller
$post->user_id = $userID;
Then querying for the user works fine
$post = Post::all();
dd($post->user); // Gets the user, no longer null
dd($post->user_id); // This is the user id field you filled out before. Returns the user id
Why this works is beyond the realm of understanding for my puny mortal mind. Interestingly there's no need to set $post->user.

I can not add methods to User Model in Laravel 5.4 ..!

I'm using Laravel 5.4. I have the methods I created in the User model. When I want to create an object from the User model and invoke my own methods, I can not get to the methods I added.
The User Model is derived from the Authenticable class at 5.4, which was derived earlier from the Model class. I think the problem is about it. What I really want to do is to set up the belong_to, has_many structure to relate the user model to the other models.
But with the User model I do not do that. What do you recommend ?
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function getMakale()
{
return $this->hasMany(Makale::class, 'user_id', 'id');
}
}
$author = User::first();
return method_exists($author,'getMakale');
//eventually turns false
I believe you are potentially setting an accessor rather than a relationship. In this case I would think you want to name that function something like:
public function haberler()
{
return $this->hasMany(Makale::class, 'user_id', 'id');
}
or public function makales(). Prefixing your function name with get or set will have unintended consequences in Laravel.

Laravel 5.3 Does protected variables in a Model act as constructor

I'm new to Laravel and I noticed some are similar to Java, some aren't. I guess it's because it uses OOP style.
I'm following a video tutorial for beginners and came across the protected modifier (if I'm correct).
I originally learned programming in Java. Below are three php file definitions.
Does the protected $fillable in the Product class act like a constructor in Java which requires you to supply values before you can create an instance of the class? (in this case, Product Class)
ProductTableSeeder.php
<?php
use Illuminate\Database\Seeder;
class ProductTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$product = new \App\Product([
'imagePath' => 'someImagePathURL',
'title' => 'Harry Potter',
'description' => 'Super cool - at least as a child.',
'price' => 10
]);
$product->save();
}
}
Product.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $fillable = ['imagePath','title','description','price'];
}
create_products_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('imagePath');
$table->string('title');
$table->text('description');
$table->integer('price');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
The line $product = new \App\Product I understand to be the instantiation part.
I'd appreciate any useful explanation to this.
Thank you.
protected $fillable = ['imagePath','title','description','price'];
It means, the field names that are given in this array can only be inserted into database from our side. Like, it is only allowed to fill values from us.
In clear, referred from document.
The $fillable property means an array of attributes that you want to be mass assignable
And,
The $guarded property means an array of attributes that you do not want to be mass assignable
Reference : https://laravel.com/docs/5.3/eloquent#mass-assignment

Categories