firemankurt
firemankurt

Reputation: 107

Querying Many to One to Relation in October CMS as a Join

Given the following October CMS Plugin Models:

Schema::create('iaff106_cellphone_cellphones', function($table){
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->integer('user_id')->unsigned()->nullable()->index();
    $table->string('label');
    $table->string('phone')->nullable()->index();
    $table->integer('provider_id')->nullable();            
    $table->boolean('is_txtable')->default(true);
    $table->boolean('is_published')->default(false);
    $table->timestamps();
    });


Schema::create('iaff106_cellphone_providers', function($table){
    $table->engine = 'InnoDB';
    $table->increments('id');
    $table->string('name');
    $table->string('slug')->index();
    $table->string('mail_domain')->nullable();
    $table->timestamps();
    }); 

Relations for Provider:

public $belongsToMany = ['IAFF106\CellPhone\Models\Cellphone', 'foreignKey' => 'provider_id'];

Relations for Cellphone:

public $hasOne = ['IAFF106\CellPhone\Models\Provider'];

I want to select a Cell Phone and the related service Provider to get the 'phone' and 'name' fields.

In my component I have tried:

public function onRun()
{
    $this->cellphone = $this->page['cellphone'] = $this->loadCell();
}

protected function loadCell()
{
    $slug = $this->propertyOrParam('idParam');
    $cellphone = Cellphone::isPublished()->where('id', '=', $slug)->first();
    $this->provider = $this->page['provider'] = $cellphone->provider;

    return $cellphone;
}

$this->cellphone has the phone data I want but I can not figure out how to access the Provider 'name' information.

How can I load and access data from both Models in the view?

I have tried this in my view:

<ul>
    <li>{{ cellphone.phone }}  {{ provider.name }} </li>
    <li>Try Again </li>
    <li>{{ cellphone.phone }}  {{ cellphone.provider.name }} </li>
</ul>

{{ cellphone.phone }} shows up fine but I can not get provider name.

Upvotes: 0

Views: 3057

Answers (2)

firemankurt
firemankurt

Reputation: 107

Thanks to Anand Patel for finding the primary problem in relations.

To make it easy for others I am posting simple but critical pieces of my code again here. I did get it working like this.

In Cellphone Model:

/**
 * @var array Guarded fields
 */
protected $guarded = [];


/**
 * @var array Relations
 */
public $belongsTo = [
    'user' =>       ['RainLab\User\Models\User', 
                    'foreignKey' => 'user_id'],
    'provider' =>   ['IAFF106\CellPhone\Models\Provider', 
                    'foreignKey' => 'provider_id']
    ];

In Provider Model:

public $hasMany = ['cellphone' =>   ['IAFF106\CellPhone\Models\Cellphone', 
                    'foreignKey' => 'provider_id']
    ];

In Component I did:

$cellphones = Cellphone::where('user_id', '=', $this->userid)->get();

In the view I did:

<ul>
{% for cellphone in cellphones  %}
    <li>
        {{ cellphone.label }} : <strong>{{ cellphone.phone }} </strong>  
        <sub>{{ cellphone.provider.name }}</sub>
    </li>
{% endfor %}
</ul>

My primary problem originally was the way I formatted the relations array. I needed to specify the key for my relations arrays. Compare my first post to this one to see what I mean.

Upvotes: 0

Anand Patel
Anand Patel

Reputation: 3943

ok fine i got the solution its a problem in your model

you need to put

public $belongsTo = [
        'provider' => ['IAFF106\CellPhone\Models\Provider', 'foreignKey' => 'provider_id']
    ];

instead of

public $hasOne = ['IAFF106\CellPhone\Models\Provider'];

here is a model code for CellPhone.php

<?php namespace IAFF106\CellPhone\Models;

use Model;

/**
 * CellPhone Model
 */
class CellPhone extends Model
{

    /**
     * @var string The database table used by the model.
     */
    public $table = 'iaff106_cellphone_cell_phones';

    /**
     * @var array Guarded fields
     */
    protected $guarded = ['*'];

    /**
     * @var array Fillable fields
     */
    protected $fillable = [];

    /**
     * @var array Relations
     */

    public $belongsTo = [
        'provider' => ['IAFF106\CellPhone\Models\Provider', 'foreignKey' => 'provider_id']
    ];

    public function scopeIsPublished($query)
    {
        return $query
            ->whereNotNull('is_published')
            ->where('is_published', '=', 1);
    }

}

please check doc for relations in October CMS https://octobercms.com/docs/database/model#relationships

and if you specify cellphone has one provider then cellphone_id must be there in your provider table, any way you will manage that your way, but the way you define relation must be like specified in doc.

component and view code just fine.

Upvotes: 3

Related Questions