7

I use in my model code to get a relation

class User extends Authenticatable
{
    // ...
    public function extensions()
    {
        return $this->belongsToMany(Extension::class, 'v_extension_users', 'user_uuid', 'extension_uuid');
    }
    // ...
}

The Extension has field password hidden.

class Extension extends Model
{
    // ...
    protected $hidden = [
        'password',
    ];
    // ...
}

Under some circumstances I want to makeVisible the password field.

How can I achieve this?

johannchopin
  • 13,720
  • 10
  • 55
  • 101
AHeavyObject
  • 562
  • 1
  • 7
  • 18

4 Answers4

14

->makeVisible([...]) should work:

$model = \Model::first();
$model->makeVisible(['password']);

$models = \Model::get();
$models = $models->each(function ($i, $k) {
    $i->makeVisible(['password']);
});

// belongs to many / has many
$related = $parent->relation->each(function ($i, $k) {
    $i->makeVisible(['password']);
});

// belongs to many / has many - with loading
$related = $parent->relation()->get()->each(function ($i, $k) {
    $i->makeVisible(['password']);
});
DevK
  • 9,597
  • 2
  • 26
  • 48
  • I tired this approach but could not find what I have to write to return from my `public function extensions()` a result with visible password. If I return `Model::get()` Collection instead of a `Illuminate\Database\Eloquent\Relations\BelongsToMany` from the method it brokes all other my things. You offer to change the type of the returning relation data. Here https://laravel.com/docs/5.4/eloquent-relationships it returns something like `return $this->belongsTo('App\User');` but not `return $this->belongsTo('App\User')->get();` – AHeavyObject May 24 '17 at 21:20
  • Updated my answer. Both last 2 are loading from a relationship. First one assumes you have loaded your relationship before, second one loads it on the go. – DevK May 24 '17 at 21:27
  • I stiil don't see how I can modify my `public function extensions()` to get the password field visible. – AHeavyObject May 24 '17 at 21:31
  • Well you can't. You can't make fields visible on query (relationships return query, not model), this all happens on model. – DevK May 24 '17 at 21:33
2

Well, I got the idea from https://stackoverflow.com/a/38297876/518704

Since my relation model Extension::class is called by name in my code return $this->belongsToMany(Extension::class,... I cannot even pass parameter to it's constructor.

So to pass something to the constructor I may use static class variables.

So in my Extension model I add static variables and run makeVisible method. Later I destruct the variables to be sure next calls and instances use default model settings.

I moved this to a trait, but here I show at my model example.

class Extension extends Model
{
    public static $staticMakeVisible;

    public function __construct($attributes = array())
    {
      parent::__construct($attributes);

      if (isset(self::$staticMakeVisible)){
          $this->makeVisible(self::$staticMakeVisible);
      }
   }
.....

    public function __destruct()
    {
      self::$staticMakeVisible = null;
    }

}

And in my relation I use something like this

class User extends Authenticatable
{
...
    public function extensions()
    {
        $class = Extension::class;
        $class::$staticMakeVisible = ['password'];

        return $this->belongsToMany(Extension::class, 'v_extension_users', 'user_uuid', 'extension_uuid');
    }
...
}
AHeavyObject
  • 562
  • 1
  • 7
  • 18
0

The highest voted answer didn't seem to work for me (the relations attribute seems to be a protected array now so can't be used as a collection in @DevK's answer), I instead used:

$parent->setRelation('child', $parent->child->first()->setVisible(['id']));
Thom Seddon
  • 1,485
  • 2
  • 15
  • 25
-1

This is working for me

$user=User::select(['id','password as user_password'])->first();
Midhun S
  • 1
  • 2