baopham / laravel-dynamodb

Eloquent syntax for DynamoDB
https://packagist.org/packages/baopham/dynamodb
MIT License
484 stars 128 forks source link

Cannot access property/attribute of returned record #277

Closed gvanto closed 5 months ago

gvanto commented 6 months ago

Describe the bug

Cannot access property 'target' of returned record.

TestController:

class TestController
{
    public function index(Request $request)
    {
/** @var DynamoDBRedirect $redir */
$redir = DynamoDBRedirect::where(['source' => 'foo'])->first();

dd($redir->target);

// Code used to create the record (OK)
//        $model = new DynamoDBRedirect([
//            'source' => 'foo',
//            'target' => 'bar',
//        ]);
//
//        $model->save();
    }
}

DynamoDBRedirect.php:

<?php

namespace App\Models;

use BaoPham\DynamoDb\DynamoDbModel;

class DynamoDBRedirect extends DynamoDbModel
{
    public $table = 'redirects';

    public $primaryKey = 'source';

    public $source;

    public $target;

    protected $fillable = [
        'source',
        'target'
    ];

    protected $guarded = [];
}

Result on test controller output:

image

Result with dd($redir): ('target' is in 'attributes' array - but can't be accessed with $redir->target ?):

image

Schema table=redirects

Item exists in DDB, call from CLI:

aws dynamodb get-item --consistent-read \ --table-name redirects \ --key '{ "source": {"S": "foo"}}' \ --endpoint-url=http://localhost:8000

Response:

{ "Item": { "created_at": { "S": "2024-01-09T14:23:01+00:00" }, "source": { "S": "foo" }, "updated_at": { "S": "2024-01-09T14:23:01+00:00" }, "target": { "S": "bar" } } }

Describe your table schema:

Debug info

Version info

gvanto commented 5 months ago

Maybe I am not "finding" the record correctly? How are attributes accessed on a given record/object?

Why does it use $model->find() rather than MyModel::find() ?

I can't see a find() method anywhere in DynamoDbModel? So if my class extends that class, how does $model->find() work?

Assuming that MyModel extends DynamoDbModel.

Finding the docs quite unclear on this ... (sample of good docs).

image

nelson6e65 commented 5 months ago

Yes, you can use the static find() normally in your model. DynamoDbModel inherits all methods from Model, just adjusting the required ones to work with Dynamo DB.

@gvanto You have some problems in your model definition:

  1. You MUST NOT add your database attributes as model properties. That will prevent them to be hydrated as attributes when fetched from the database; remove them.
  2. You are using $fillable and $guarded together. It is not recommended to use $fillable and $guarded together because they have opposite effects; $fillable allows only the specified attributes to be mass assigned, while $guarded blocks only the specified attributes from being mass assigned.

As recommendation, you can use a sub-namespace for DynamoDb models (App\Models\Dynamo\...) instead of using a prefix in the model name. With this, you can take advantage of the automagic benefits of Laravel's models for table names and else.

And, sorry for the lack in the documentation. I had not have much time to make some improvements I planned to. That's in the roadmap tho.