Set user field on the fly

I tried to set a user field on the fly but i couldt make it.

on controller file

$user->skills = page('skills')->children();

on view file

$user->skills; // working, data exists but methods not working

$user->skills(); // not working never

I want to use second one because of using as page object like that:

if($user->skills()->count() > 0)
{
    // todo
}

I tried following too but same issue:

$user->set('skills', page('skills')->children());

It should be, just like with pages:

$user->update(array(
  'skills' => $stringValue
));

You have to convert your skills collection to a YAML string first though.

No no no! I dont want to save any data. Just append new data dynamicly.

What do you want to append the data to? Is there a field “skills” in your user file and what sort of content does it contain?

Ah, alright.

In theory that would be $user->data['skills'] = $value, but since the data attribute is protected, you can’t modify the data from outside the User class.

Why do you need to set the data on the user object directly? Couldn’t you return the skills as a separate variable from your controller?

@texnixe See the controller code in the first code block. He wants to set the value to a page collection from a controller.

@lukasbestle I’ve seen that and was just wondering why @ahmetbora doesn’t save this to a variable.

Why collection::set(key, value) method doest work?

For example users have many portfolios, education, certificates, skills that pages collection all.

I want to append portfolios, education, certificates, skills that filtered with filterBy('user', $user_id) to user profile.

In your theory, i can save only pages uid as string (tags field), i will think about…

@texnixe I do not want to inflate with huge data on user profile.

If Kirby supported User models like you proposed last week, it would be no problem because you could then extend your users with whatever data dynamically. Until then, there’s no really elegant way to do this unfortunately. Using a tags field to define the skills is the best way until then IMO.

collection::set() doesn’t work because a user is no collection. :wink:

Saving only pages uid to user like @texnixe said seems to be the only solution.

So i have a question for you @texnixe and @lukasbestle :smile:

Which method more fast and performance ?

1. Filtering (current method)

$portfolios = page('portfolios')->children()->filterBy('user', $user_id);

2. Finding (discussion on this topic)

$portfolios = array();
foreach(explode(',', $user->portfolios()) as $uid)
{
   $portfolios[] = page('portfolios')->find($uid);
}

I think first method more eligible for me. What do you think? Thanks.

They are basically equally fast, I’d not expect a huge difference in performance. I think the first one is a bit more robust though, it also seems to make more sense semantically in this case.

Edit: Actually the first one will need to open all content files of the children to read the user field. The second solution would not need to do this. But if you don’t have thousands of portfolios, it doesn’t matter.

1 Like

Good point! At least 100 users and each user have 10 portfolios, so minumum 1000 portfolios… And skills, educations, certificates etc, second method more performance in this case. really thx @lukasbestle