troelskn / laravel-fillable-relations

Provides HasFillableRelations trait to Eloquent models
63 stars 23 forks source link

Nested belongsTo relationship #8

Open johnwilhite opened 6 years ago

johnwilhite commented 6 years ago

This is a similar issue to https://github.com/troelskn/laravel-fillable-relations/issues/5.

The trait is failing on the following example:

$contract = new Contract([
    'price' => '12',
    'customer' => [ // belongsTo relation
            'name' => 'First Last',
            'reference' => [ // hasMany relation
                [
                    'name' => 'First Last'
                ]
            ]
        ]
    ]
]);

The fillBelongsToRelation save for customer fails with the following, because it's trying to select reference, which is the relation and not a column, from the customers table.

Column not found: 1054 Unknown column 'reference' in 'where clause' 

The following seems to fix the issue for belongsTo relations, it's extracting the relations out and only using the attributes in that lookup.

    /**
     * @param BelongsTo $relation
     * @param array|Model $attributes
     */
    public function fillBelongsToRelation(BelongsTo $relation, $attributes, $relationName)
    {
        $entity = $attributes;
        if (!$attributes instanceof Model) {
            if (method_exists($relation->getRelated(), 'extractFillableRelations')) {
                list($relations, $attributes) = $relation->getRelated()->extractFillableRelations($attributes);
            }

            $entity = $relation->getRelated()
                ->where($attributes)->firstOrFail();
        }
        $relation->associate($entity);
    }

Would this be an appropriate fix? Also I haven't tested the belongs to many, but I'd imagine it would need a similar fix.

troelskn commented 6 years ago

Hi John. Sorry for the late response.

Could you supply the db schema and the full model code that you are using?

FredrikBergelin commented 4 years ago

This is how I just managed to solve it, I think. Haven't tested it thoroughly. Makes sense?

public function fillBelongsToRelation(BelongsTo $relation, $attributes, $relationName)
{
    $entity = $attributes;
    $created = self::getModelName($relationName)::create($entity);
    $relation->associate($created);

    // if (!$attributes instanceof Model) {
    //     $entity = $relation->getRelated()
    //         ->where($attributes)->firstOrFail();
    // }
    // $relation->associate($entity);
}
private static function getModelName($name)
{
    return 'App\Models\' . rtrim(ucfirst($name), 's');
}