Yii: Inserting database relations manually - php

There are 2 simple tables (MyIsam):
Child:
id(PK),
name,
land_id(FK)
Land:
id(PK),
name
These are the both Models (excerpt):
Following changes has no effects, if I modify the Models and let create the crud-forms, there are no changes and die land_id is getting no data from land table:
Model Child.php (excerpt)
class Child extends CActiveRecord
{
...
public function relations()
{
return array(
'land_id'=>array(self::BELONGS_TO, 'Land', 'id'),
);
}
...
}
Model Land.php
class Land extends CActiveRecord
{
...
public function relations()
{
return array(
'id'=>array(self::HAS_MANY, 'Child', 'land_id'),
);
}
...
}
Where is my mistake ?
EDIT: Do I need some more work, to get a select box with the corresponding land list in the created insert form (via CRUD) ?
thank you..

MySQL’s MyISAM engine does not support foreign keys at all.
Use InnoDB!

Related

How do you define a 1-1 relationship bidirectionally with phalcon?

I have two tables, work_order and project. On the project records, there is a work_order_id field. There is no project_id on the work_order records. Do I need to add one?
Or is there a way to define these relationships using hasOne/belongsTo?
I've tried:
class WorkOrder extends \Phalcon\Mvc\Model {
public function initialize() {
$this->hasOne('id', Project::class, 'work_order_id');
}
}
class Project extends \Phalcon\Mvc\Model {
public function initialize() {
$this->hasOne('work_order_id', WorkOrder::class, 'id');
}
}
I can retrieve the WorkOrder from the project like so: $project->workOrder, but I cannot retrieve a Project from a WorkOrder using $workOrder->project. I want a bidirectional relationship.
How do I do this?
Try adding the alias parameter, since the implicit retrieval might try to use the class name and it wouldn't support namespaces in your models.
I found it quite bogus in phalcon 1/2/3 to work with hasOne. I've been using belongsTo since then until I re-wrote the pre-post-save part of the phalcon relationship manager for my personal needs. Keep in mind that belongsTo will be saved before the main model you are working with, other types of relationships will be created/updated after the main record is saved. I choose to use "belongsTo" or "hasOne" depending on the order that I want the records and their relationships to be saved.
class WorkOrder extends \Phalcon\Mvc\Model {
public function initialize() {
$this->belongsTo('project_id', Project::class, 'id', ['alias' => 'Project']);
}
}
class Project extends \Phalcon\Mvc\Model {
public function initialize() {
$this->hasOne('id', WorkOrder::class, 'project_id', ['alias' => 'WorkOrder']);
$this->hasMany('id', WorkOrder::class, 'project_id', ['alias' => 'WorkOrderList']);
}
}
Implicit retrieval should start with a ucfirst camelized string of your class name, or using a get.
$workOrder = WorkOrder::findFirst();
$project = $workOrder->Project;
$project = $workOrder->getProject(['deleted <> 1']);
$workOrderList = $project->WorkOrderList;
$workOrder = $project->WorkOrder;
$workOrder = $project->getWorkOrder(['deleted <> 1', 'order' => 'projectId desc']);

Invalid object name with Many to Many Relationship with 2 DB Connections

I am building a training web application to track associate training and certifications. I have created an Associate model that used a secondary DB connection to another database that has its information generated by another application so I have no control over the structure of the data. The associates table uses the associate's number as primary key and not an auto incremented ID. I have created a table to keep track of every training/certification course that take place. I created a many to many relationship between the Associate and the Course but when trying to add a record to the pivot table I am running an error.
"SQLSTATE[42S02]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid object name 'associate_course'. (SQL: insert into [associate_course] ([associate_id], [course_id], [created_at], [updated_at]) values (0000, 1, 2020-01-31 18:36:56.390, 2020-01-31 18:36:56.390))",
Here is the function that is called to create a record in the pivot table (where the error occurs)
public function trained(Course $course, Request $request) {
$request->validate([
'associates' => 'required'
]);
$associates = explode(',', $request->associates);
foreach($associates as $associate_number) {
$associate = Associate::where('NUMBER', $associate_number)->first();
$course->associates()->attach($associate);
}
}
Here is my Associate model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Associate extends Model
{
protected $connection = 'SHOPFLOOR';
protected $table = 'USERS';
public function getRouteKeyName()
{
return 'NUMBER';
}
public function courses()
{
return $this->belongsToMany(Course::class, 'associate_course', 'associate_id', 'course_id', 'NUMBER', 'id')->withTimestamps();
}
}
and here is my Course model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Course extends Model
{
protected $fillable = ['course_type_id', 'name', 'date', 'expires', 'expires_at', 'notification_threshold'];
public function type() {
return $this->belongsTo(CourseType::class);
}
public function associates() {
return $this->belongsToMany(Associate::class, 'associate_course', 'course_id', 'associate_id', 'id', 'NUMBER')->withTimestamps();
}
}
I tried copying the sql from the error and running it on the database and it does insert the row into the database so that leads me to believe it's something with my Laravel configuration?
Can I get some assistance in fixing this issue?
It's hard to say without seeing your DB structure, Error says clearly that table specified in query is not found. Most probably is that you forgot to specify schema in the statement. IMHO code that you showed is not really related to the problem.
There is a bug with the Laravel sqlsrv driver. I needed to specify the full schema to get it working. In my case this was TRAINING.dbo.associate_course.
So relationships look like this
Associate.php
public function courses()
{
return $this->belongsToMany(Course::class, 'TRAINING.dbo.associate_course', 'associate_id', 'course_id', 'NUMBER', 'id')->withTimestamps();
}
Course.php
public function associates() {
return $this->belongsToMany(Associate::class, 'TRAINING.dbo.associate_course', 'course_id', 'associate_id', 'id', 'NUMBER')->withTimestamps();
}

Yii2. Models related

I have 3 models: Items, Serials and SerialsCategories. When I show Item form (to create or update) I need to show the serials which belongs to a categoryId selected in a previous step. A serial can belong to more than one category.
Right now I have on my Item model:
public function getSerialsTypeByCategory() {
return (new SerialType)->getByCategory($this->itemCategoryId);
}
On my SerialType model:
public function getByCategory($itemCategoryId) {
return SerialTypeItemCategory::find()->select(['serialTypeId'])->where(['itemCategoryId' => $itemCategoryId])->all();
}
This is working, it does what I need but ... Is this the proper way? is there a better way?
it's not wrong what you are doing. but there is something more -
check this link:
Working with Relational Data
if you use ->hasOne and ->hasMany to define relations, your model gains some extra benefits, like joining with lazy or eager loading:
Item::findOne($id)->with(['categories'])->all();
with a relation, you can also use ->link and ->unlink, to add/delete related data without having to think about linked fields.
Further, it is easy to define relations via junction table:
class Order extends ActiveRecord
{
public function getItems()
{
return $this->hasMany(Item::className(), ['id' => 'item_id'])
->viaTable('order_item', ['order_id' => 'id']);
}
}

Add field to an Eloquent model

So I have two Laravel/Eloquent models, and I want to add one more field to one of them.
Model 'Car' gets data from table 'cars' and has fields 'id', 'model', 'color' and 'price'. Model 'Person' has fields 'id', 'name' and 'car_id', which is foreign key from 'cars' table. I want model 'Person' to have a field named 'car', which would contain car model from 'Car' model, depending on existing car_id. I've tried something like:
use App\Models\Car;
class Person extends Model {
protected $car = array(Car::find($this->car_id));
}
But that was unsuccessful (errors like 'syntax error, unexpected '(', expecting ')''). What could be the solution? Thanks!
You need to define One-To-Many relationship first. Then get car model for the person:
$carModel = Person::find($personId)->car->model;
Take a look at Eloquent Relationships. What you are trying to do is to create a relationship between Car and Person models. It is up to you if a person can own one or multiple cars. I am suggesting you to let a person have multiple cars.
So, the Person model should know that it has multiple cars:
class Person extends Model
{
public function cars()
{
return $this->hasMany(App\Car::class);
}
}
A car belongs to a person, so the model should know that:
class Car extends Model
{
public function person()
{
return $this->belongsTo(App\Person::class);
}
}
Of course, when creating the tables you should add the field person_id to the CARS table.
Well, what I needed was:
protected $appends = ['car'];
public function getTypeAttribute($car)
{
return Car::find($this->car_id)->model;
}
It was all about serialization and 'protected $appends', thank you all :)
That's not how its done.
The person can have a car (or many). Let's suppose that every person have one car in your database, your car table should have a nullable person_id column, and add this to your User model
public function car() {
return $this->hasOne('App\Role');
}
Now you can get the person and the his car information's like this
User::where('id',$id)->with('car')->get();
I hope you get the point here

YII Active Record Join

I am looking at YII for the first day, and i'm having some problems trying to work out the relations between some tables.
my table structure is as follows:
Pets:
pet_id
pet_name
....
Pet_Owner_Link
pet_id
owner_id
Owner:
owner_id
owner_name
How would I go about getting all of the pets that belong to an owner? Really struggling to get my head around the AR relations at the moment.
Per this comment by DD.Jarod on the Yii AR documentation page: http://www.yiiframework.com/doc/guide/1.1/en/database.arr#c970
"If you declare a many to many relationship, the order of keys inside the jointable declaration must be 'my_id, other_id':
class Post extends CActiveRecord
{
public function relations()
{
return array(
'categories'=>array(self::MANY_MANY, 'Category',
'tbl_post_category(post_id, category_id)'),
);
}
}
class Category extends CActiveRecord
{
public function relations()
{
return array(
'Posts'=>array(self::MANY_MANY, 'Post',
'tbl_post_category(category_id, post_id)'),
);
}
}
So your code would look like:
class Owner extends CActiveRecord
{
public function relations()
{
return array(
'pets'=>array(self::MANY_MANY, 'Pet',
'tbl_post_category(pet_id, owner_id)'),
);
}
}
class Pet extends CActiveRecord
{
public function relations()
{
return array(
'owners'=>array(self::MANY_MANY, 'Post',
'tbl_post_category(owner_id, pet_id)'),
);
}
}
Your problem may be that your primary keys for Pet and Owner by default should be id (not pet_id / owner_id). Yii may be getting confused if you don't clarify that your primary keys don't match the default naming convention / aren't setup as primary keys in the database. You can specify what your primary key is in a model like this:
public function primaryKey()
{
return 'owner_id';
}
Finally, you would retrive the information like this:
$owner = Owner::model()->findByPk((int)$id);
foreach($owner->pets as $pet)
{
print $pet->name;
}
I know this is not exactly what you ask, but this is how I do it.
Add this item in your relations() return in Owner model :
'all_pets'=>array(self::HAS_MANY, 'Pet_Owner_Link','owner_id'),
Add this item in your relations() return in Pet_Owner_Link model :
'pet'=>array(self::BELONGS_TO, 'Pet', 'pet_id'),
Then get a pet like this
$owner->all_pets[$i]->pet;

Categories