How to get a Model data while creating referenced of its

Person model has: id, … | a person has many notes, has many book
Note model has: id, person_id, book_id … | a note is belong to one person
Book model has: id, person_id, note_amount, name …

In a Person.php have ngRestRelations like below

public function ngRestRelations()
    {
        return [
            ['label' => 'Note',
            'targetModel' => \app\modules\infomation\models\Note::class,
            'dataProvider' => $this->getNote(),
            'tabLabelAttribute' => 'tabNote',
            ]
        ];
    }

With this, in the list of Person, I have a button to for creating a Note for this Person. How the id of this person have been passed to this Note creating? In the Note model, I want to use/get the id of this person to find the books, which this person having. How to do?

in the Note.php I have this, I just want to distplay the situation of the book, not selecting. But now, I just do like this. Any suggestion?

public function ngRestAttributeTypes()
    {
//...
'book_id' => [
                     'selectModel',
                     'modelClass' => Boook::className(),
                     'valueField' => 'id',
                     'sortField' => 'id',
                     'labelField' => function($model) { //$model or someting else?
                                        //return 'dont have a book' if the person of creating note don't have any book or book with note_amount = 0.
                                        //return name of A book if the person of creating note have a book with note_amount > 0. Then The note_amount will reduce 1.
                                    },
                  ],
//...
}

Hi @mrtrinhvn

first: Please try to format your post, so its more easy for use to read and help, check intending of your code and use ``` to quote the code.

Summary of your relations?

I have a button to for creating a Note for this Person.

Are you building those forms in the LUYA admin ui? or are you using frontend with controllers to build those things? `

in the Note.php I have this, I just want to dist play the situation of the book, not selecting. But now, I just do like this. Any suggestion?

If you just want to display something in the admin ui, use extrafields, see: https://luya.io/guide/ngrest-model section extra fields.

‘selectModel’,
‘modelClass’ => Boook::className(),

Using select model can be dangerous if you are using yii hasMany/hasOne relations which requires the id, while luya selectModel will assign the actuall value to the attribute. See the note https://luya.io/guide/ngrest-plugin-select at the end

1 Like

first: Please try to format your post, so its more easy for use to read and help, check intending of your code and use ``` to quote the code

Sorry for this, I don’t know this before :smiley:

Summary of your relations?

Note may hasOne or None book. So, Is the relation hasOne() is suitable ?

If you just want to display something in the admin ui, use extrafields, see: https://luya.io/guide/ngrest-model 1 section extra fields.

I want to show the situation of the person(in this, person’s book) while creating a note for a person. if the person have books, show “Book: name of last book”. If he doesn’t, show “Book: none”. How to do that?

Because creating the Note for an existing person, but while creating a note, I need person’s id to find his book, so I created this topic about “How to get a Model data while creating referenced of its”
Even more, I want to access more attribute of the person

Please help me resolved this!

I want to show the situation of the person(in this, person’s book) while creating a note for a person. if the person have books, show “Book: name of last book”. If he doesn’t, show “Book: none”. How to do that?

So you like to do this in admin LUYA Admin create form?

Maybe you could create a dropdown select for the user:

public function ngrestAttributeTypes()
{
    return [
        'book' => ['selectArray', 'data' => $this->getSelectData()],
    ];
}

public function getSelectData()
{
     $userId = Yii::$app->adminuser->id;
     // query data for the user .. or not 
     // and return an array with "none" or the given books, or the single book.
    return [
        null => 'No Book',
        1 => 'Book ID #1'
    ];
}

This way the user could choose from your custom user defined dropdown.

If this does not suit your use case, you can always create custom ngrest plugins, https://luya.io/guide/ngrest-plugins#create-a-custom-project-plugin see section Create a custom project Plugin.

1 Like

So you like to do this in admin LUYA Admin create form?

Maybe you could create a dropdown select for the user:

Thank you for the idea, but I think not used for my case.

This is for a person, eg. a student. I think, the the person’s id already sent to the Note create form. So, after a note created, it belong to the person, right? We don’t have to select person while creating a note.
Can I get the person’s id, or other person’s other data then using or process it on the create from?
I want to show(not selecting) the status of this student’s books on the Note create form

you should always be able to create a getter method, assign into extra fields and display that field only in the create form.

getMyExtraData()
{
   return '<h1>hello world</h1>';
}

Let LUYA Admin know what data plugin should be used for the given value, for example raw (or https://luya.io/api/luya-admin-ngrest-plugins-Angular)

public function ngRestExtraAttributeTypes()
{
    return [
        'myExtraData' => 'raw',
    ];
}

Now assign the new getter method from extra fields into a scope
, in your case, create:

public function ngRestScopes()
{
    return [
        ['list',  ...],
        [['create'],  ['myExtraData']],
    ];
}

If this does not work, i am not sure i can help you. otherwise you maybe need to upload the data somewhere and show us some screenshots and let us know where you like to display which data.

Here is my clip showing the case
There is English Sub with the clip

Thanks for the video, it explains to me (hopefully :slight_smile:) what you are trying to do. You like to have a dropdown with all books which belong to the current student when you create a new NOTE for this student. right?

  1. a list of students
  2. you click on the list of notes for the given student.
  3. you try to create a new note inside this relation and like to show all books belong to the student

I need to research a bit, to check whether there is a solution, but out of the box this does not work yet. Could you create an ngrest extra field with the angular plugin, dumping the context? Cause i think then we need to make a call to an api and returns those books to create the dropdown.

public function ngRestExtraAttributeTypes()
{
    return [
        'test' => ['class' => Angular::class, 'template' => '{{ item | json }} | {{ data | json }}'],
    ];
}

add the test attribute to the list of attributes in create scope

public function ngRestScopes()
{
    return [
        [['create'], ['test']],
    ];
}

And show me the output. I think the id of the student should be available within data or item, then you can make an xhr request to an api, returning all books and render a dropdown.

In the Node model I have added

use luya\admin\ngrest\plugins\Angular;
...
 public function rules()
    {
        return [
          [[..., 'test'], 'string', 'max' => 255],
        ];
    }
...
public function ngrestExtraAttributeTypes()
   {
       return [
           'test' => ['class' => Angular::class, 'template' => '{{ item | json }} | {{ data | json }}'],
       ];
   }
...
public function ngRestScopes()
    {
        return [        
            [['create'], ['test', ...]],
        ];
    }

And the result

I think this new feature should fix your problem, could you please take a look? https://github.com/luyadev/luya-module-admin/pull/612/files

Great!
I wonder if it work with extra fields?

Yes it does. The plugins is now available in the dev-master branch. For more details take a look at https://github.com/luyadev/luya-module-admin/blob/master/src/ngrest/plugins/SelectAsyncApi.php

Thank you for this new feature!
I hope this make our luya more popular!
I have try, it can show the original fields, but extra fields, Is there anything not complete?

Every plugin can be used as extraField. As i can not guess what you have configured, i am unable to help. If you need help or want have a proper answer you need to provide more informations, like configuration, etc.

In the Note.php

    public function ngRestAttributeTypes()
    {

        return [

            'student_id' => [
                     'selectModel',
                     'modelClass' => Student::className(),
                     'valueField' => 'id',
                     'labelField' => function($model) {
                                        return "$model->ho  $model->ten ($model->sdt)";
                                    },
                 ],
            'book_id' => [
                'class' => SelectAsyncApi::class,
                'api' => 'admin/api-studentinfo-book/search?query={student_id}',
                     'labelField' =>  'bookinfo',
                     'valueField' => 'id'
            ],

    }

========================

in the Book.php

public function extraFields()
    {
        return ['bookinfo'];
    }

public function getStudent()
    {
        return $this->hasOne(Student::class, ['id' => 'student_id']);
    }

 public function getBookinfo()
    {
            $d = date("d/m/Y", $this->created_timestamp);
          return  "$this->student->name $d";
    }

After all, the result is



If i change the book_id to

'book_id' => [
                'class' => SelectAsyncApi::class,
                'api' => 'admin/api-studentinfo-book/search?query={student_id}',
                     'labelField' =>  'noteamount', // This notenum is a original field in a Book
                     'valueField' => 'id'
            ],

The result is

i even add to thê Note.php like below:

public function getBookinfo()
    {
            $d = date("d/m/Y", $this->created_timestamp);
          return  "$this->student->name  $d";
    }

public function getStudent()
    {
        return $this->hasOne(Student::class, ['id' => 'student_id']);
    }

public function extraFields()
    {
        return ['bookinfo'];
    }

No error occur, but nothing shown :smiley:

Then you need to expand the extra field in the rest call. RESTful Web Services: Resources | The Definitive Guide to Yii 2.0 | Yii PHP Framework

admin/api-studentinfo-book/search?query={student_id}&expand=bookinfo

ps: For debugging purposes it would be nice to see what your xhr response looks like.

1 Like

Thank you, it is work!!! THANK YOU @nadar

For debugging purposes it would be nice to see what your xhr response looks like

After this, please help me to do:

  1. A field value to be set when I select a book**. Eg, the field below - “Phí” should be set to 10, the amount of notes in the book, and the field should read only. Can we do that. It mean that, other field may be controlled by selecting book ??

  2. If there 0 or 1 book:

  • If the student have No bookThe book Dropdown should be hide, (As web know, books are not required when creating a Note).
  • If there is only 1 book. It should displayed its name instead of showing dropdown for selecting book.

this is not possible, you have to create your own plugins. I think this topic is closed now.

1 Like

OK, I think this could be closed now, and I think this thead is very useful for Luya Community
I may open another topic to find solution for the next problems
Thank you!