2017-07-18 43 views
-1

是否可以覆蓋- > get() Eloquent中的方法以始終自定義數據庫查詢中所選字段的輸出?Laravel 5 - 覆蓋獲取或從中選擇

例如,如果你做一個平常口若懸河的查詢,如:

User::where('email','like','%wherever.com')->get(); 

代替它使查詢:

Select name, email, address, created_at from users where email like '%wherever.com' 

是否有可能重寫總是返回類似的方法:

Select CONCAT('CL::',name), lower(email), address, created_at from users where email like '%wherever.com' 

我問 - >因爲我看到我可以傳遞一個數組與c要選擇的列,但我不想在所有查詢中定義它們。

回答

1

因此,圍繞功能挖掘有關查詢後,我發現這個解決方案:

我創建了一個新的類CustomQueryBuilder,它擴展了照亮\數據庫\查詢\生成器

在那裏,你可以通過Eloquent覆蓋get()/ select()/ where()方法。

然後,在你要更改的查詢時的方式,定義字段更改喜歡的機型:

protected $encrypted = [ 
    'name', 
    'email', 

]; 

在此之後,我創建了一個新的類CustomModel,它擴展了照亮\數據庫\雄辯\型號並有覆蓋newBaseQueryBuilder這樣的:

protected function newBaseQueryBuilder() 
{ 
    $connection = $this->getConnection(); 

    return new CustomQueryBuilder(
     $connection, $connection->getQueryGrammar(), $connection->getPostProcessor(), $this 
    ); 
} 

裏面的CustomQueryBuilder您可以根據需要自定義構建器的所有方法。

有了這個設置,你可以在任何照亮\數據庫\雄辯\型號改變它來擴展你的CustomModel和繼承爲指定的列這個特殊的行爲。

要知道,從擴展CustomModel模型進行的所有查詢都將得到這個新的方法,所以做所有需要的檢查,不要亂用雄辯的正常行爲,這樣的事情:

public function where($column, $operator = null, $value = null, $boolean = 'and') 
{ 

    if ($this->model !== null && isset($this->model::$encrypted)) 
    { 
     if (in_array($column, $this->model::$encrypted)) 
     { 
      $column = DB::raw("CONCAT('CL::',$column)"); 
     } 
    } 

    parent::where($column, $operator, $value, $boolean); 

} 

PS :我知道這聽起來很愚蠢與CONCAT示例,但與$加密屬性,你可以找出它不是串聯字符串。

0

爲什麼你需要重寫get或select方法?在您的用戶模型中創建一個功能

public static function specialSelect($name, $email, $address) //or array of them 
{ 
    $result = //your special queries come here 
    return $result; 
} 

然後像User::specialSelect()一樣使用它。

+0

是的,但我真正想要的是像平常一樣使用Eloquent,並且能夠始終自定義列。假設你想在模型內部鏈接一個where條件到你的函數,但是你不能,但是如果你重寫這些方法中的一個,無論你做什麼查詢,你總會收到相同的數據 – user2048076

0

您可以使用模型來更新結果爲特定領域如下面

使用此代碼模型文件聯繫CL::' with the name`值

public function getNameAttribute($value) { 
     return 'CL::'.$value; 
    } 

您只需調用User::where('email','like','%wherever.com')->get();這樣

getNameAttribute函數將始終返回名稱值與「CL ::」

所以喲你不需要在你的查詢中加上CONCAT('CL::'.name)

可以查詢的結果時,增加對其他領域也


更新 解決方案相同的方式

在模型中加入這個geofields

protected $geofields = array("concat('CL::',name) as name"); 

添加此newQuery功能以覆蓋列

public function newQuery($excludeDeleted = true) 
    { 
     $raw=''; 
     foreach($this->geofields as $column){ 
      $raw .= $column; 
     } 

     return parent::newQuery($excludeDeleted)->addSelect('*',\DB::raw($raw)); 
    } 

希望這是你所期望的。

+0

感謝Hari,但是如果你這樣做那麼,只能在查詢數據庫後修改數據,我的意圖是修改他的根上的數據,而不是查詢後的查詢。 concat函數只是一個例子,我真正想要做的是解密,但用法可以相同 – user2048076

+0

你是對的。但這個例子是忽略每個查詢中的'concat'。 如果你想在他的根上的數據,你需要做你的查詢'concat'.I不認爲有其他的方式。 – Hari

+1

但這不是被問到的。我需要總是發送** concat **,而不是在每個查詢中定義它,所以我相信如果我重寫select來更改列或者如果我能夠修改也接受列的get,則此問題我只是無法找到如何擴展雄辯或覆蓋他的方法 – user2048076