I've found a complete solution around the problem with using $model->setHidden(array $columns);
Lets say, for example, that you would like to decide in the controller exactly which fields to return. Updating only the model's hidden forces you to go over each model before you return an array of models for example. The problem becomes even worse when those models have relationships that you would also like to change. You have to loop over each model, set the hidden attribute, and then for each also set the relationships hidden. What a mess.
My solution involves creating a static member for each model that when present, updates the visible/hidden attribute just before the call to "toArray":
<?php
trait DynamicHiddenVisible {
public static $_hidden = null;
public static $_visible = null;
public static function setStaticHidden(array $value) {
self::$_hidden = $value;
return self::$_hidden;
}
public static function getStaticHidden() {
return self::$_hidden;
}
public static function setStaticVisible(array $value) {
self::$_visible = $value;
return self::$_visible;
}
public static function getStaticVisible() {
return self::$_visible;
}
public static function getDefaultHidden() {
return with(new static)->getHidden();
}
public static function geDefaultVisible() {
return with(new static)->getVisible();
}
public function toArray() {
if (self::getStaticVisible())
$this->visible = self::getStaticVisible();
else if (self::getStaticHidden())
$this->hidden = self::getStaticHidden();
return parent::toArray();
}
}
As an added bonus, I expose a way to the model's default hidden/visible that you may have set in your model's class.
Don't to forget to add the trait
class Client extends Eloquent {
use DynamicHiddenVisible;
}
Finally, in the controller, before returning your model, decide on visible/hidden attributes:
public function getIndex($clientId) {
// in this specific call, I would like to hide the "special_type" field of my Client model
$hiddenFields = Client::getDefaultHidden();
array_push($hiddenFields, "special_type");
Client::setStaticHidden($hiddenFields);
return Client::find($clientId)->toJson();
}