0
votes

I'm having troubles to setup the right Eloquent relationships (belongsTo, hasMany, ...) for a pivot table.

I will abbreviate code for clarity. I have two important tables: 'parties' and 'p2p_relations'. This is the migration for parties

public function up()
    {
        Schema::create('parties', function ($table) {
            $table->increments('id');
            $table->string('name');
            $table->unsignedInteger('kind');
            $table->timestamps();
            $table->softDeletes();

            $table->foreign('kind')->references('id')->on('kinds');
        });
    }

This is the migration for p2p_relations (party to party relations)

public function up()
    {
        Schema::create('p2p_relations', function ($table) {
            $table->bigIncrements('id');
            $table->unsignedInteger('context');
            $table->unsignedInteger('reference');
            $table->datetime('start');
            $table->datetime('end')->nullable();
            $table->unsignedInteger('kind')->nullable();
            $table->timestamps();
            $table->softDeletes();

            $table->foreign('context')->references('id')->on('parties');
            $table->foreign('reference')->references('id')->on('parties');
            $table->foreign('kind')->references('id')->on('kinds');
        });
    }

The model for Party

class Party extends Ardent
{
    use SoftDeletingTrait;

    protected $softDelete = true;
    protected $dates = ['created_at', 'updated_at', 'deleted_at'];

    protected $table = 'parties';

    public static $rules = array(
        'name' => 'required',
        'kind' => 'required|numeric'
    );

}

The model for Relation

class Relation extends Ardent
{
    use SoftDeletingTrait;

    protected $softDelete = true;
    protected $dates = ['created_at', 'updated_at', 'deleted_at'];

    protected $table = 'p2p_relations';

    public static $rules = array(
        'context' => 'required|numeric',
        'reference' => 'required|numeric',
        'kind' => 'required|numeric',
        'start' => 'required|date',
        'end' => 'date'
    );
}

How can I set relationships so I can associate parties as context or reference in a relationship. I thought belongsTo will help like so in class Relation

public function context() {
        return $this->belongsTo('Party', 'context', 'id');
    }
    public function reference() {
        return $this->belongsTo('Party', 'reference', 'id');
    }

But when I run this unit-test I get an error: Undefined property: Relation::$context

$context = new Party();
        $context->name = 'Person A';
        $context->kind = 1;
        $context->save();

        $ref = new Party();
        $ref->name = 'Company B';
        $ref->kind = 2;
        $ref->save();

        $relation = new Relation();
        $relation->start = new DateTime();
        $relation->context()->associate($context);
        $relation->reference()->associate($ref);
        $relation->kind = 3;
        $relation->save();

Any thoughts? I'm really a newbie to this framework.

1
Try taking a look at the documentation. laravel.com/docs/4.2/eloquent#relationships You shouldn't be required to manually define the relationship model. - Kao
Thus putting following to Party model: public function context() { return $this->belongsToMany('Party', 'p2p_relations', 'context'); } public function reference() { return $this->belongsToMany('Party', 'p2p_relations', 'reference'); } But how can I add extra attributes on the relationships? as start, kind, ... - BakGat
@jaan First off read the docs, check withPivot, wherePivot methods. Then, fix the relationships from your comment. Next check this out: github.com/jarektkaczyk/Eloquent-triple-pivot - Jarek Tkaczyk

1 Answers

1
votes

Thanks to the comments provided I've learned a lot :-)

Updated my Party Model:

public function references() {
    return $this->belongsToMany('Party', 'p2p_relations', 'context', 'reference')
        ->withPivot('reference', 'start', 'kind')
        ->withTimestamps()   ;
}

No Relation model needed.

The pivot table works perfectly.

Thanks