Relationship between tables (hasOne) Object of class ... could not be converted to string - cakephp-3.x

I have 2 tables one of images that belong to several different tables and in the other table the reference for id_imagen with the id of the table images.
Table Documentos:
id | id_imagen | titulo | texto
Table Imagenes:
id | tabla | imagen | tipo
Relationship:
Doumentos.id_imagen = Imagenes.id
In the model of images I have put:
$this->belongsTo('Escudos', [
'className' => 'Documentos',
'foreignKey' => 'id_imagen',
'conditions' => ['tabla' => 'escudos']
]);
In the model of documentos I have put:
$this->hasOne('Imagenes');
In the documentos controller:
$imagenes = TableRegistry::get('Imagenes');
$documentos = TableRegistry::get('Documentos');
$documentos = $imagenes->$documentos
->find('all')
->select(['Documentos.id', 'Documentos.titulo', 'Documentos.texto', 'Imagenes.imagen'])
->all();
$this->set('documentos', $documentos);
I get the following error:
Warning (4096): Object of class App\Model\Table\DocumentosTable could not
be converted to string [APP/Controller/DocumentosController.php, line 21]

Look at what you are doing in line 21:
$imagenes->$documentos
You are passing $documentos as the propery name to access on $imagenes, that's of course not going to work, as $documents is an object, as the error message suggests.
The documentos variable shouldn't be there in the first place. You want to query on $imagenes:
$imagenes->find()->/* ... */
Besides that your associations are not setup correctly, the Escudos association must be hasOne (the other table has the foreign key), and the Imagenes association must be belongsTo (the current table has the foreign key). Also as you are using non-conventional column names, you must at least configure the foreign key for the Imagenes association too.
Cookbook > Database Access & ORM > Associations - Linking Tables Together

In the end I found the solution:
Documentos table:
$this->hasOne('Imagenes')
->setBindingKey('id_imagen')
->setForeignKey('id');
Imagenes table:
$this->belongsTo('Documentos')
->setForeignKey('id_imagen')
->setJoinType('INNER');
Documentos Controller:
public function Documento() {
$documentos = TableRegistry::get('Documentos');
$documentos = $documentos->find('all')
->contain(['Imagenes']);
$this->set('documentos', $documentos);
}
view:
<?= $documento->imagen->imagen; ?>

Related

How do I get the model instance inline with the main Eloquent query by foreign key reference

My question is simple.
I have 2 tables. "Users" and "Access Levels".
The Access Levels table contains the names of the available levels on the site. Something like this:
Access Level Table
id
name
1
admin
2
subscriber
And in the Users table, I'm using the access_level through foreign key. Something like this:
Users Table
id
username
access_level
1
user1
1
2
user2
2
3
user3
2
Now I'm querying all the user in usercontroller with User:all(). The results return a collection which includes the access_level id as expected. But I want to include the name of the associated access_level within the same result set/collection. I've tried searching for Eloquent relationships, but I'm not able to understand the concept.
This is the result that I'm expecting:
Array(
[id => 1,username => user1, access_level => admin],
[id => 2,username => user2, access_level => subscriber],
[id => 3,username => user3, access_level => subscriber],
)
EDIT
After applying the code as suggested by #xenooo, I see that it returns the results with a "relations" key which has the foreign_key model instance. I've done your implementation on another set of tables. This time, in place of users, its books. And category in place of access_level. This is the response that I get with dd(). I've used the following code,
$books = Book::with('category')->find(1);
dd($books);
dd of response
First you must define the relationship of your database to your model. Assuming that you have a model for AccessLevel :
// app/Models/AccessLevel.php
public function users() : HasMany
{
return $this->hasMany(User::class, 'access_level');
}
// app/Models/User.php
public function accessLevel() : BelongsTo
{
return $this->belongsTo(AccessLevel::class,'access_level');
}
To include the relationship when querying.
User::with('accessLevel')->get(); // accessLevel is the name of the function you define.

OctoberCMS belongsTo relationship saving problem

I have two models:
Brands
Mods
I can display all brands via belongsTo function. Problem is when I try to save same brand two times, I get error duplicated entry.
This belongsTo is causing duplicated entry error when saving to DB two same brands.
Mods.php
public $belongsTo = [
'brand' => [\Slasher\Farming\Models\Brands::class, 'key' => 'id'],
];
This belongsToMany works, and save's data to DB, but is generating checkbox field (I only want to select one brand at one mod enty). I'm using pivot table for this relation.
Mods.php
public $belongsToMany =[
'brand' =>[
'Slasher\Farming\Models\Brands',
'table' => 'slasher_farming_mods_brands',
'order' => 'brand_name'
],
];
BelongsTo example: (Brands are visible and I can save them. But problem is when saving same brand for more than two times).
Error I get when saving with belongsTo.
I tried also creating inverse relationships on Brands model with (belongsTo and belongsToMany), but still getting this error.
What type of relation should I make, to save Brands as dropdown list and to fix this duplicate error?
If you're using a pivot table for your relation, then you should use $belongsToMany. Pivot table is only used for many-to-many relations.
I fixed this problem with changing column in the mods name brand to brand_id and also changing belongsTo relation. I just removed key, and it works like a charm. No need for pivot table here.
Mods.php
public $belongsTo = [
'brand' => ['Slasher\Farming\Models\Brands']
];
"SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3' for key 'PRIMARY' (SQL: update liam_blog_blogs set id = 3, liam_blog_blogs.updated_at = 2022-07-26 09:30:09 where id = 2)"

backpack for laravel Add Colum from related table

I have table 3 tables, equipment(ID, name)
parameters(ID, name) and the pivot table equipment_parameter(equipment_id, parameter_id) , on my "Equipment" list view i need to add a column with the name of the parameter so i need to retrieve name from the Parameter table.
Equipment Model:
public function parametros(){
return $this->belongsToMany('App\Parametro','equipo_parametro','equipo_id',
'parametro_id')->withTimestamps();
}
Parameter model:
public function equipos(){
return $this->belongsToMany('App\Equipo','equipo_parametro','parametro_id',
'equipo_id')->withTimestamps();
}
i added this on equipmentCrudcontroller ,but have had no success.
$this->crud->addColumn([ // Select
'label' => 'Parametro',
'type' => 'select2',
'name' => 'equipo_id', // the db column for the foreign key
(not sure here since equipment foreign key is on pivot table????)
'entity' => 'parametros', // the method that defines the relationship in your Model
'attribute' => 'nombre', // foreign key attribute that is shown to user
'model' => "App\Parametro" // (doubt, there's a pivot table inbetween???) foreign key model
]);
If you are adding a column and have already run the previous migration you can create a new migration php artisan make:migration update_equipment_table inside of that, you can then do something like this
Schema::table('table', function (Blueprint $table) {
$table->string('column');
});
then rerun migrations php artisan migrate this will add the new column to your table.

Eloquent relationship in Laravel

I'm having following table structure:
Table Name - Users
Column: id, name, email, etc
Table Name - Plugins
Column: id, theme_id, type_id, code,
Table Name - Templates
Column: id, theme_id, user_id, templatedata
Table Name - Userplugins
Column: id, user_id, plugins_id, contents
Now I'm calling the route with id of the templates, in which templatedata has JSON data, i'm able to get Plugins code by following code in my blade file as:
#foreach($gettemplate as $renderer)
{!! $plugins->find($renderer)->code !!}
#endforeach
but I'm unable to fetch contents in the UserPlugins table. Following is my controller where I'm trying to do so:
public function get_template($id)
{
$template = Template::findOrFail($id);
$gettemplate = json_decode($template->templatedata);
$plugins = Plugins::all();
$user = User::findorFail($id);
return $user->userplugins()->contents;
//return view('nitseditor.test', ['plugins' => $plugins, 'gettemplate' => $gettemplate, 'user' => $user]);
}
I've commented out my view just to check the output.
I've defined the relationship in the model my App/User.php file contains:
public function userplugins(){
return $this->hasMany('App\UserPlugin');
}
And in App\UserPlugin.php file I've:
protected $fillable = [
'contents',
];
I'm getting the following error:
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$contents
Please help me out, Thanks.
In the following line:
return $user->userplugins()->contents;
When you call $user->userplugins() that mean you call an relation method. It's will not return Eloquent Collection or Eloquent Object for you.
You need to call
$user->userplugins
to get collection of UserPlugin
However, when you call
return $user->userplugins->contents;
you will get error, becauese return $user->userplugins is an Eloquent Collection, you can not get contents from it.
You can get the contents of specific UserPlugin. For example, the first UserPlugin of user like:
return $user->userplugins()->first()->contents;

cakePHP 3 save data in Many to Many relationship

I have Employees and Complexes in a Many to many relationship.I have used the
bake console to generate models, controllers... for Employees and Complexes tables.
My questions is :
-Since I have in my BD The table "complexes_employees", do I have to bake also Model
and controller for this Table too or cakePHP is able to know that it contains the
two foreign keys of Employees and Complexes.
Second question :
-How can I save my data in this Three tables. for my app I have to save employees
per Complex .
// Employees Controller
public function addEmpPerComplex($id_complex){
$emp = $this->Employees->newEntity();
if ($this->request->is('post')) {
$employee = $this->Employees->patchEntity($employee, $this->request->data, ['associated'=>['Complexes._joinData']] );
//here I need to insert the record that contains the employee data in Employees Table
// then I need to insert in "complexes_employees" the ID of Complex sended in parametre of this function and the ID of the new Employee
Thanks for helping me
Do I have to bake also Model and controller for this Table?
No, CakePHP will use the abstract Table class. However, if you need extra information for this relationship, then you will need to create a join model. Check http://book.cakephp.org/3.0/en/orm/associations.html#using-the-through-option
How can I save my data in this Three tables?
As long as your data has the id of a related entity, it will automatically be saved both entity and relation:
$data = [
//employee data,
'complexes' => [
['id' => $id_complex]
]
]
$this->Employees->patchEntity($employee, $data, [
'associated' => ['Complexes']
]);
/*
Saves both the new Employee and the relation
(employeed id and complex id in complexes_employees)
*/
$this->Employees->save($employee);
For more information: http://book.cakephp.org/3.0/en/orm/saving-data.html#saving-belongstomany-associations

Resources