8000 $select should only have effect on primary entity · Issue #255 · flat3/lodata · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

$select should only have effect on primary entity #255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Angelinsky7 opened this issue May 10, 2022 · 5 comments
Closed

$select should only have effect on primary entity #255

Angelinsky7 opened this issue May 10, 2022 · 5 comments

Comments

@Angelinsky7
Copy link

Context

class Person {
  #[LodataRelationship]
    public function tags(){
        return $this->belongsToMany(Tag::class);
    }
}

class Tag {
}

Db

Table person{id}
Table tags{id}
Table person_tag{person_id,tag_id}

Request
http://localhost:8080/odata/Person?$select=id$expand=tags

Result

[
 {
    id 1,
    tags: [
      {id: 1},
      {id: 2}
    ]
 },
 {
    id 2,
    tags: [
      {id: 3},
      {id: 4}
    ]
 }
]

Expected result

[
 {
    id 1,
    tags: [
      {id: 1, prop1: '', prop2: ''},
      {id: 2, prop1: '', prop2: ''}
    ]
 },
 {
    id 2,
    tags: [
      {id: 3, prop1: '', prop2: ''},
      {id: 4, prop1: '', prop2: ''}
    ]
 }
]

Only with this request : http://localhost:8080/odata/Person?$select=id$expand=tags($select=id) we should have the actual result.

Proposal
Iv'e made some test and it seems that with this commit things are working correctly for simple cases : Angelinsky7@985118e but because i don't have a correct knowledge of out work it's difficult to see if it's the correct way of resolving this issue.

Version
"flat3/lodata": "^5.11"

@27pchrisl
Copy link
Contributor

Hi, thanks for the detailed report!

I wasn't able to reproduce this behaviour where the $select appears to cascade down to the navigation properties using a new Laravel project with an sqlite database and the structure of People and Tags that you have there.

Using the request http://localhost:8000/odata/People?$expand=tags&$select=id I received:

{
    "@context": "http://localhost:8000/odata/$metadata#People(id,tags())",
    "value": [
        {
            "id": 1,
            "tags": []
        },
        {
            "id": 2,
            "tags": [
                {
                    "id": 3,
                    "name": "c"
                },
                {
                    "id": 4,
                    "name": "d"
                }
            ]
        }
    ]
}

Is there more information on your setup you could share?

@Angelinsky7
Copy link
Author

@27pchrisl wahou, i'm really sorry.
After all my experimentation i've made some errors.
So you are right in the case of the collection the issue does not appear ! Only with "simple" navigation link :

http://localhost/odata/People?$expand=link,tags&$select=id

class People extends Model
{
    protected $table = 'peoples';

    use HasFactory;

    #[LodataRelationship]
    public function link(){
        return $this->belongsTo(Link::class, 'link_id');
    }

    #[LodataRelationship]
    public function tags(){
        return $this->belongsToMany(Tag::class);
    }

}

class Tag extends Model
{
    use HasFactory;
}

class Link extends Model
{
    use HasFactory;
}
Schema::create('peoples', function (Blueprint $table) {
  $table->id();
  $table->string('lastna
8000
me');
  $table->unsignedBigInteger('link_id');
  $table->timestamps();

  $table->foreign('link_id')->references('id')->on('links');
});
{
  "@context": "http://localhost/odata/$metadata#People(id,link(),tags())",
  "value": [
    {
      "id": 1,
      "link": {
        "id": 1
      },
      "tags": [
        {
          "id": 1,
          "name": "eveniet",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        },
        {
          "id": 2,
          "name": "et",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        },
        {
          "id": 3,
          "name": "fugit",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        }
      ]
    },
}

we can see in this example that the link does not contains the correct fields....

with my corrections we have the correct result

{
  "@context": "http://localhost/odata/$metadata#People(id,link(),tags())",
  "value": [
    {
      "id": 1,
      "link": {
        "id": 1,
        "value": "asperiores",
        "created_at": "2022-05-10T20:35:45+00:00",
        "updated_at": "2022-05-10T20:35:45+00:00"
      },
      "tags": [
        {
          "id": 1,
          "name": "eveniet",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        },
        {
          "id": 2,
          "name": "et",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        },
        {
          "id": 3,
          "name": "fugit",
          "created_at": "2022-05-10T20:35:40+00:00",
          "updated_at": "2022-05-10T20:35:40+00:00"
        }
      ]
    },
}

@Angelinsky7
Copy link
Author
Angelinsky7 commented May 10, 2022

But i realize now that my correction is not correct. The more i think about it the more it feels that (sorry if i'm wrong and seems saying bad things ) the way navigation properties are handle is not correct.

I think it could be due to the way you handle properties of navigation properties
If we look at #256 it seems parts of the same issue where the information of the EntitySet that owns the current properties is lost

in this case

public function emitJson(Transaction $transaction): void
call shouldEmit with the context of the primary EntitySet (People) but should in reality be called with it's own EntitySet context ( Link ) .

a good example would be to use this request http://localhost/odata/People?$expand=link($select=value),tags&$select=lastname and see that link is always empty ! (because there is no property lastname on the Link EntitySet)

In the other case (but it should certainly be in another thread), we can see that the owner of the properties is "always" lost and we assume that it's always the primary EntitySet

public function tokenizeDeclaredProperty(): bool
{
$currentResource = $this->getCurrentResource();
if (!$currentResource) {
return false;
}

@27pchrisl
Copy link
Contributor

Hi @Angelinsky7, thanks for the detailed issue report! There seems to be a common element to these reports, that effectively when using query parameters with $expand notation, the correct parameters are not used.

For expansion Lodata creates a sub-request with all the parameters provided for expansion, but when Lodata looked for a set of transaction parameters to use this sub-transaction was not being correctly attached, which meant the upstream or main transaction was being used.

Could you install flat3/lodata:5.x-dev and see if this issue is fixed?

@27pchrisl
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants
0