Datamapper in Code Igniter deals with a relationship as many to many - codeigniter

I have a very confusing problem..
I configured data mapper and started to use it with code igniter.. I have this class:
class FamilyMemberDetail extends DataMapper {
var $table = "family_members_details";
var $has_one = array('gender', 'maritalstate');
public function __toString() {
return is_string($this->id) ? $this->id : "";
}
}
For gender it is working fine..
class Gender extends DataMapper {
var $table = "genders";
var $has_many = array("familymemberdetail");
public function __toString() {
return is_string($this->gender_label) ? $this->gender_label : "";
}
}
But with marital status:
class MaritalState extends DataMapper {
var $table = "marital_state";
var $has_many = array("familymemberdetail");
public function __toString() {
return is_string($this->marital_state_label) ? $this->marital_state_label : "";
}
}
I get this error!
Error Number: 1146
Table 'elkhoudary_family.kh_family_members_details_marital_state' doesn't exist
SELECT `kh_marital_state`.* FROM (`kh_marital_state`) LEFT OUTER JOIN `kh_family_members_details_marital_state` kh_family_members_details_marital_state ON `kh_marital_state`.`id` = `kh_family_members_details_marital_state`.`maritalstate_id` WHERE `kh_family_members_details_marital_state`.`familymemberdetail_id` = 1
Filename: C:\AppServ\www\elkhoudary\system\database\DB_driver.php
Line Number: 330
The problem is that I didn't specify this relationship to need a join table and yet.. CI insists that it needs a table in between.. isn't it supposed to work like gender.. what am I missing here?

Ok I found out why and it is really stupid.. the relation column should be named [className]_id not [tableName]_id and since I have my class named "MaritalState" and my table name "marital_state".
So I changed all entities to '_'s instead of Camel cases and everything went fine..
class Family_member_detail extends DataMapper {
var $table = "family_members_details";
var $has_one = array('gender', 'marital_state');
public function __toString() {
return is_string($this->id) ? $this->id : "";
}
}
Gender:
class Gender extends DataMapper {
var $table = "genders";
var $has_many = array("family_member_detail");
public function __toString() {
return is_string($this->gender_label) ? $this->gender_label : "";
}
}
Marital State:
class Marital_state extends DataMapper {
var $table = "marital_state";
var $has_many = array("family_member_detail");
public function __toString() {
return is_string($this->marital_state_label) ? $this->marital_state_label : "";
}
}

Related

Laravel model with custom generated id

In my Demande model, for the ID I have not used the default incremental id, not even the ulid. I have customized the generation of the id. But the issue is that when you call it in route, that id is not recognized and the item cannot be found.
The snippet of my model is :
class Demande extends Model
{
protected static function boot()
{
parent::boot();
static::creating(function (Demande $demande) {
$demande->id = self::generateCode($demande->matricule);
});
}
}
Where the generateCode() function is :
public static function generateCode(string $matricule): string
{
// {$this->matricule}-{increment} for example: 2021020061-01
// make sure the code is unique
$count = self::where('matricule', $matricule)->count() + 1;
return $matricule . Str::padLeft($count, 2, '0');
}
With the snippet of the route call :
Route::resource('demandes', DemandeController::class);
In DemandeController, if i do this in the show function :
public function show(Demande $demande)
{
$title = $demande->code;
$etudiant = $demande->etudiant;
....
return view('admin.demandes.show', compact('demande', 'title', 'etudiant'));
}
This throws an error that $demande object is not found. And I am oblidged to change into :
public function show($demande)
{
$demande = Demande::find($demande);
$title = $demande->code;
$etudiant = $demande->etudiant;
....
return view('admin.demandes.show', compact('demande', 'title', 'etudiant'));
}
where I get that $demande param as ID and manually do the find.
Is there a setting inside Demande model or anywhere that needs to be set so that the custom generated id be recognized ?

How to change connection of eager loading?

These are my models
class Posts extends Model {
protected $connection = 'connection_1';
public function comments()
{
$model = new Comments();
$model->setConnection($this->connection);
return $this->hasMany($model, 'comments_id');
}
}
class Comments extends Model {
protected $connection = 'connection_1';
public function author()
{
$model = new Authors();
$model->setConnection($this->connection);
return $this->hasOne($model, 'id', 'authors_id');
}
public function post()
{
$model = new Posts();
$model->setConnection($this->connection);
return $this->hasOne($model, 'id', 'posts_id');
}
}
class Authors extends Model {
protected $connection = 'connection_1';
public function comments()
{
$model = new Comments();
$model->setConnection($this->connection);
return $this->hasMany($model, 'authors_id');
}
}
When i put this code in my controller, Comments model is connected to connection_2 but Authors is empty, i guess it's not changing connection to connection_2
$posts = new Posts;
$posts->setConnection('connection_2');
$posts->load("comments.author")->get();
How can I change dinamically Authors model connections, or why Authors is empty?
I have resolved my problem like this:
$conn = \App\Helpers\Helper::connection($item_id);
$newPdo = \DB::connection($conn)->getPdo();
\DB::setPdo($newPdo);
$posts = \App\Posts::with("comments.author")->get();
And in my helper
public static function connection($project) {
switch($project) {
case 01:
return 'connection_01';
break;
case 02:
return 'connection_02';
break;
case 03:
return 'connection_03';
break;
}
}

How inject parameter in model constructor?

I'm trying to use mutator to change price property before saving in database. I want to inject discount parameter and use it in mutator like below. I'm getting error "Column not found: 1054 Unknown column 'discount' in 'field list" Is it possible to inject parameter in model constructor?
class Pizza2 extends Model
{
public $table = 'pizza2';
public $timestamps = false;
public $fillable = ['name', 'price'];
public function __construct($d = null)
{
$this->discount = $d;
}
public function setPriceAttribute($value)
{
if ($this->discount) {
$this->attributes['price'] = $value * $this->discount;
} else {
$this->attributes['price'] = $value;
}
}
}

Laravel one-to-many save Carbon error

I have a class called SubjectData:
class SubjectData extends Model
{
protected $table = 'subject_datas';
protected $fillable = ['firstname','lastname','birthdate','birthcity','months'];
protected $dates = ['birthdate'];
public function setBirthdateAttribute($date)
{
// So we can add the time, not just he php date
$this->attributes['birthdate'] = Carbon::createFromFormat('d/m/Y', $date);
}
public function anamnesis() {
return $this->belongsTo('App\Anamnesis');
}
}
And I have a class called Anamnesis:
class Anamnesis extends Model
{
public function meetingTest() {
return $this->belongsTo('App\MeetingTest');
}
public function subject() {
return $this->belongsTo('App\Subject','subject_id','id');
}
public function subjectData() {
return $this->hasOne('App\SubjectData');
}
public function scholarHistory() {
return $this->hasOne('App\ScholarHistory');
}
public function familyHistory() {
return $this->hasOne('App\FamilyHistory');
}
public function psicodiagnosis() {
return $this->hasOne('App\Psicodiagnosis');
}
}
The store function of the SubjectController class works like this:
public function store(CreateSubjectRequest $request)
{
$input = $request->all();
// Let's generate the anamnesis of the subject
$anamnesis = Anamnesis::create();
$anamnesis->save();
$newSubjectData = $this->saveSubjectData($input);
$anamnesis->subjectData()->save($newSubjectData);
......
......
}
where the function called is:
public function saveSubjectData($input)
{
$subjectData['firstname'] = $input['firstname'];
$subjectData['lastname'] = $input['lastname'];
$subjectData['birthcity'] = $input['birthcity'];
$subjectData['birthdate'] = $input['birthdate'];
return SubjectData::create($subjectData);
}
The problem is with the "birthdate" property.
If i check the value of $newSubjectData (dd($newSubjectdata)) after the call $this->saveSubjectData($input) the value of the birthdate is exactly the one i set on the calendar in the frontside (and also in the db the value is correct)
If I put the dd($anamnesis->subjectData) after the call $anamnesis->subjectData()->save($newSubjectData) the result is the "today" date and also in the DB the value is not the one I set but the date of today.
I can't find the error
P.S. The calendar is inside a Vue template
I think the problem is that, the date must be an instance of Carbon or is properly formatted according to your database table. Try the following inside your saveSubjectData() method
$subjectData['birthdate'] = Carbon\Carbon::parse($input['birthdate']
I write down the answer but i thank John Aldrin that guided me in the right direction.
You have to put the timestamp('birthdate') AFTER the default timestamps of the migration table (so at the end of the migration table)
I don't know why. If someone knows please explain !

Laravel Saving A Model And Relationships

I have the following Model:
class Movie extends Eloquent {
protected $primaryKey = "movie_id";
public function detail()
{
return $this->hasOne('Detail');
}
public function firstpage()
{
return $this->hasOne('Firstpage');
}
public function country()
{
return $this->belongsToMany('Countries','movies_countries','movie_id','country_id');
}
public function year()
{
return $this->hasOne('Years');
}
public function media() {
return $this->hasMany('Media');
}
}
This is the Model of interest:
class Years extends Eloquent {
protected $table = 'movies_years';
protected $primaryKey = "relation_id";
public function movie()
{
return $this->belongsTo('Movie');
}
The DBTable for years has a field "movie_year" and "movie_id"
So, I have following problem, or understanding issue:
I'm trying to update the Model Years with new Data, but can't seem the get it done. I tried the following:
$movies = Movie::find($tmp['movie_id']);
$movies->title = $tmp['title'];
$movies->title_product = $tmp['title_product'];
$movies->title_orginal = $tmp['title_original'];
$movies->year = array('movie_year' => $tmp['movieyears']);
$movies->push();
The eye is on the $movies->year row, everything else works fine.
I also tried something stupid like:
$movies->year() = array('movie_year' => $tmp['movieyears']);
I don't know how to update the Years Model, which has a relation with the Movie Model.
The offical way would be using attach, sync or associate methods. These methods are described at http://laravel.com/docs/eloquent-relationships#inserting-related-models
In your case, you'd have to do something like this:
$movies->year()->attach($tmp['movieyears']);
To remove the relation (not the Movie or Year), use detach().

Resources