如何在使用 eloquent 时排除某些列

2021-12-26 00:00:00 php laravel eloquent

当我使用 eloquent 时,我可以使用where"方法,然后使用get"方法来填充包含我在数据库中选择的对象的对象.我的意思是:

When I'm using eloquent, I can use the "where" method then the method 'get' to fill an object containing what I've selected in my database. I mean:

$users = User::where('gender', 'M')->where('is_active', 1)->get(['pseudo', 'email', 'age', 'created_at'])->toArray();

在这里我可以选择我想要的列,如伪"、电子邮件"等.但是我在 laravel doc 中想念的是相反的方法.可能是这样的:

Here I can choose the columns I want to get like 'pseudo', 'email', etc.. But what I miss in laravel doc is the way to do the contrary. It could be something like that:

$users = User::where('gender', 'M')->where('is_active', 1)->notGet(['pseudo', 'email', 'age', 'created_at'])->toArray();

感谢您的回答,祝您有美好的一天.

Thank you for you futur answer and have a nice day.

推荐答案

如果您只需要从模型的数组或 JSON 表示中隐藏属性,您可以使用一种或两种方法:

If you only need to hide attributes from your model's array or JSON representation, you may use one or both approaches:

  • 添加$hidden 属性给你的模型
  • Add the $hidden property to your model
class User extends Model
{
    /**
     * The attributes that should be hidden for arrays.
     */
     protected $hidden = ['password'];
}

  • 使用makeHidden功能

    $users = $users->makeHidden(['address', 'phone_number']);
    

  • 有关更多详细信息,请参阅其他答案... 但是 有时您不想将大量数据(地理空间、html、日志...)加载到您的应用程序中,它会很慢并且需要更多的记忆.OP 要求进行 SQL 查询,因此我的回答是,但大多数情况下,仅从 JSON 响应中隐藏数据会更方便.

    See other answers for more details... But sometimes you don't want to load huge data (geospatial, html, logs...) into your application, it will be slow and take more memory. OP asked for an SQL query hence my answer, but most of the time it's more convenient to only hide the data from the JSON response.

    AFAIK SQL 中没有内置选项来显式排除列,所以 Laravel 不能这样做.但是你可以试试这个技巧

    AFAIK there is no build in option in SQL to exclude columns explicitly, so Laravel can't do it. But you can try this trick

    更新

    另一个技巧是指定模型中的所有列(或使用额外的查询来使用 $this->getTableColumns() 从 这个答案,也可以在每次迁移后缓存以避免两次查询)然后添加一个局部作用域 函数

    Another trick is to specify all columns in your model (or use an extra query to get all columns using $this->getTableColumns() from this answer, it can also be cached after each migration to avoid two queries) then add a local scope function

    // The below code requires you to define all columns in $columns.
    // A better approach is to query the schema of the table and cache it after each  
    // migration, for more details: https://stackoverflow.com/a/56425794/3192276
    
    protected $columns = ['id','pseudo','email'];
    
    public function scopeExclude($query, $value = []) 
    {
        return $query->select(array_diff($this->columns, (array) $value));
    }
    

    然后你可以这样做:

    $users = User::where('gender', 'M')
        ->where('is_active', 1)
        ->exclude(['pseudo', 'email', 'age', 'created_at'])
        ->toArray();
    

    相关文章