#php #laravel #eloquent
#php #laravel #eloquent
Вопрос:
Всякий раз, когда я использую eloquent model, она будет выбирать *, если я не укажу это в объекте querybuilder. Однако я хочу указать разрешенные поля в классе. Это было бы полезно для обеспечения того, чтобы пользователь правильного уровня получал сведения, на которые он имеет право, чтобы это свойство соответствовало классу.
Я хочу иметь возможность делать это как переменную-член, например $with:
/**
* @property mixed id
*/
class Attribute extends Model
{
protected $fillable = ["id", "business_id", "attribute_name"];
protected $with = ["attributeDetail", "business"];
protected $selectedFieldsThatMeanSelectStarDoesntHappen = ["id", "business_id", "attribute_name"];
}
Таким образом, любой запрос, использующий вышеупомянутый класс, будет выполняться SELECT id, business_id, attribute_name
всякий раз, когда используется класс, а не SELECT *
.
Существует ли вышеуказанная функциональность? Самое близкое, что я могу получить, — это глобальная область видимости:
class Attribute extends Model
{
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function booted()
{
static::addGlobalScope('selectFields', function (Builder $builder) {
$builder-&&t;select("id", "business_id", "attribute_name");
});
}
}
Комментарии:
1. как насчет глобальной области видимости? laravel.com/docs/7.x/eloquent#&lobal-scopes
2. @la&box Хороший, я об этом не подумал. Я хотел бы видеть что-то подобное в моем вопросе в laravel, но глобальная область действия позволила бы достичь того, что я ищу
3. Для некоторого контроля над показанным / скрытым атрибутом в зависимости от пользователя вам следует использовать ресурсы коллекции или JsonResponse (если это api). laravel.com/docs/7.x/eloquent-resources
Ответ №1:
Вы можете попробовать это: создайте новый конструктор и признак для использования этого нового конструктора:
class BuilderWithSpecifiedColumns extends Builder
{
public $selectedColumns = [];
public function __construct(ConnectionInterface $connection, Grammar $&rammar = null, Processor $processor = null, array $selectedColumns = ['*'])
{
parent::__construct($connection, $&rammar, $processor);
$this-&&t;selectedColumns = $selectedColumns;
}
/**
* @param strin&[] $columns
* @return IlluminateSupportCollection
*/
public function &et($columns = ['*'])
{
return parent::&et($this-&&t;selectedColumns ? $this-&&t;selectedColumns : $columns);
}
}
trait HasSelectedColumns
{
protected function newBaseQueryBuilder()
{
$connection = $this-&&t;&etConnection();
return new BuilderWithSpecifiedColumns(
$connection,
$connection-&&t;&etQueryGrammar(),
$connection-&&t;&etPostProcessor(),
$this-&&t;selectedFieldsThatMeanSelectStarDoesntHappen,
);
}
}
Используйте вышеуказанную черту
/**
* @property mixed id
*/
class Attribute extends Model
{
use HasSelectedColumns;
protected $fillable = ["id", "business_id", "attribute_name"];
protected $with = ["attributeDetail", "business"];
protected $selectedFieldsThatMeanSelectStarDoesntHappen = ["id", "business_id", "attribute_name"];
}