This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

lucas.sanner54070
lucas.sanner54070

Hi all,

I'm new to October CMS and I'm a bit confused regarding relations and the way to use them in the fields.yaml file.
Here's my user relation in my Plugin.php file:

public function boot()
 {
   User::extend(function ($model) {
     $model->hasMany['articles'] = ['Company\PluginName\Models\Article', 'key' => 'created_by'];
   });
 }

and the reversed relation in my model:

class Article extends Model
{
   ...
   public $belongsTo = [
      'user' => ['Backend\Models\User', 'key' => 'created_by']
   ];
}

my fields.yaml

user:
    tab: company.pluginname::lang.attribute.tab_manage
    label: company.pluginname::lang.attribute.created_by
    type: relation
    select: last_name
    disabled: true

The last name of the user is diplayed as expected in the field. But what if I want to display 2 columns (ie: first_name AND last_name) ? I tried several ways but none of them worked

select: first_name,last_name    
select: [first_name,last_name]
...

Can someone help me ?

mjauvin
mjauvin

Use type=partial instead of type=relation and use this in your partial:

<?= $this->relationRender('user') ?>

Also, what does you config_relation.yaml looks like ?

lucas.sanner54070
lucas.sanner54070

Thanks for your response. Unfortunately I get this error:
Method [relationRender] does not exist on [Company\PluginName\Controllers\Articles]
Any idea ?

lucas.sanner54070
lucas.sanner54070

Ok I figured out how to set it up but I'm still having issues.

fields.yaml

user:
    tab: company.pluginname::lang.attribute.tab_manage
    label: company.pluginname::lang.attribute.created_by
    type: partial
    path: $/company/pluginname/controllers/articles/_user.htm
    disabled: true

My controller:

class Articles extends Controller
 {
 public $implement = [
     'Backend.Behaviors.FormController',
     'Backend.Behaviors.ListController',
     'Backend.Behaviors.RelationController' // <= add this
 ];      

 public $formConfig = 'config_form.yaml';
 public $listConfig = 'config_list.yaml';
 public $relationConfig = 'config_relation.yaml'; // <= add this

config_relation.yaml

user:       
 label: company.pluginname::lang.attribute.created_by
 view:
   form: $/company/pluginname/models/article/fields.yaml
 manage: 
   form: $/company/pluginname/models/article/fields.yaml
   list: $/company/pluginname/models/article/columns.yaml

But now I get this error:
Model 'Backend\Models\User' does not contain a definition for 'categories'.

Maz
Maz

Hi, I prefer use accessor in this case of computed properties on relationship instead of create a new partial file just to display an informational field.

For your situation it would be something like:

fields.yaml -> I changed the field name for user_field to not interfer with an eventual user attribute, and the first underscore says to october to not submit the field

_user_field:
    tab: company.pluginname::lang.attribute.tab_manage
    label: company.pluginname::lang.attribute.created_by
    disabled: true

in your model Article.php:

public function getUserFieldAttribute() {
    return $this->user->first_name . ' ' .$this->user->last_name;
}

More infos about accessors

More infos about the underscore

Last updated

lucas.sanner54070
lucas.sanner54070

Thanks for the tip. You're right, the "accessor approach" is much more simpler and it works out of the box.
Regarding the "partial approach" I'm still wondering what a definition for 'categories' has to do with my user field...
If someone has an answer, I'm interested.

Last updated

Maz
Maz

I'm also curious. What was the content of your partial file and your full fields.yaml? It seems like you were asking for a categories field somewhere...

Last updated

lucas.sanner54070
lucas.sanner54070

I think you put your finger on the root of the problem. Indeed I have a categories field in my fields.yaml

categories:
    tab: company.pluginname::lang.attribute.tab_category
    type: relation

But I need this field. So according to this post I put my user field in a separated file and set the paths accordingly.

It works now but this is not what I want.
I end up with 5 CRUD buttons reading "Create Created by", "Update Created by" and so forth.
All I want is a simple disabled field showing 2 values. I'm not sure that the "partial approach" is appropriate.
@mjauvin could you please be more specific about how to achieve that with partial ?

ps: I think we have a bot in the thread: onlinlivehelp24754091

Last updated

Maz
Maz

I'm convinced the accessors way should work, you should inspect why the categories relation is not set.

Can you shows us your full Article model file? It seems like you missed to declare the relationship like this:

I assume your are creating a "blog-like" plugin in my next snippet code.

class Article extends Model
{
   ...
   public $belongsTo = [
      'user' => ['Backend\Models\User', 'key' => 'created_by']
      'category' => ['Namespace\Plugin\Category']
   ];
}

And you should rename the "categories" field to "category" in your fields.yaml file.

Last updated

lucas.sanner54070
lucas.sanner54070

I think you got me wrong, the accessors way does work and so does the partials way. The thing is, as I mentioned earlier, that with the partials way I don't get what I expect.

nb: I don't use $belongsTo for the category model as I want my articles to belong to several categories.

class Article extends Model
{   
   use \October\Rain\Database\Traits\Validation;

  /**
   * @var string The database table used by the model.
   */
  public $table = 'company_pluginname_articles';

  ...

  public $belongsTo = [
      'user' => ['Backend\Models\User']
  ];
  public $belongsToMany = [
     'categories' => [
         'Company\PluginName\Models\Category',
         'table' => 'company_pluginname_articles_categories',
         'order' => 'name'
     ]
  ];

  ...

  public function getUserFieldAttribute() {
    return $this->user->first_name . ' ' .$this->user->last_name;
  }

  ....
Maz
Maz

Oh yeah sorry I misunderstood...

To do with the partial way with a read-only field, you can pass some config parameter to the relationRender method, it will disable the toolbar.

<?= $this->relationRender('user', ['readOnly'  => true]) ?>

If you need more precise configuration, such displaying update/create button but not delete, you need to use a config_relation file

Last updated

mjauvin
mjauvin

The accessor way works when displaying a relation that is selected elsewhere. If you need to select the relation in your form, you'd need to either use the partial method or use this select line in your relation field definition:

select: concat(first_name, " ", last_name)
lucas.sanner54070
lucas.sanner54070

Great, this is what I was lookink for from the very start
select: concat(first_name, ' ', last_name)
But anyway, I've learned several approaches which can be useful too.

1-13 of 13

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.