2016-12-01 60 views
2

我有一個CMS,允許用戶保存和創建自行車遊覽。每個自行車之旅還有類別,這些類別使用​​Laravel的多對多關係利用中間樞軸表進行定義。在保存遊覽時,我們不知道遊覽是正在編輯的現有遊程還是新遊程。Laravel 5:如何使用firstOrNew與其他關係字段

認爲我應該使用Laravel的firstOrNew方法來保存旅程,和sync方法來保存類別。然而,所有的教程很簡單地只給路過一個對象的功能,像這樣的例子:

$tour = Tour::firstOrNew($attributes); 

但會發生什麼,當我$attributes還包含額外的東西,像它鏈接到關係表的類別,而且我需要在下一步中保存哪些內容?例如this very good tutorial給出了下面的例子:

$categories = [7, 12, 52, 77]; 

$tour = Tour::find(2); 

$tour->categories()->sync($categories); 

但是,如果類別數據是捆綁在一起的旅遊其餘的數據,而不是使用find我需要使用firstOrNew創建旅遊會發生什麼?在我實例化遊覽時,是否應該將類別保留在$attributes中,然後運行sync,然後在保存遊覽之前取消它們,或者......?有沒有更好的方法來實現這一目標?

編輯:需要明確的是,在我這裏例如$attributes變量基本上是捆綁在一起 - 就像Laravel /雄辯系統將使用與subequent修改從belongsToMany方法 - 對交易歸還巡演對象數據用戶)。即:這裏是它所包含的內容快照:

array (
    'id' => 1, 
    'uid' => '03ecc797-f47e-493a-a85d-b5c3eb4b9247', 
    'active' => 1, 
    'code' => '2-0', 
    'title' => 'Tour Title', 
    'url_title' => 'tour_title', 
    'distance_from' => 20, 
    'distance_to' => 45, 
    'price_from' => '135.00', 
    'price_to' => '425.00', 
    'created_at' => '2013-12-31 15:23:19', 
    'updated_at' => '2015-07-24 16:02:50', 
    'cats' => // This is not a column name! 
    array (
    0 => 1, 
    1 => 7 
), 
) 

所有這些屬性都在我的旅行團表的列名,比貓等,它通過的hasMany關係引用另一個表。在設置這個對象類之前,我是否需要手動取消它的設置並將其保存爲$tour->save

我在找最乾淨的大多數Laravel的方法嗎?

EDIT2:這裏是在圖爾模型中定義的關係:

class Tour extends Model 
{ 

    protected $guarded = []; 

    public function cats(){ 
     return $this->belongsToMany('App\TourCategory', 'tour_cat_assignments', 'tour_id', 'cat_id'); 
    } 
} 
+1

不知道我是否明白你的觀點。但由於你不提及它...你有沒有嘗試過[水合](https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_hydrate)或[fill](https:// laravel.com/api/5.0/Illuminate/Database/Eloquent/Model.html#method_fill)? – alariva

+1

從來沒有聽說過這些,看起來很有前途 - 謝謝! – Inigo

+0

讓我們貼出! – alariva

回答

0

您可以使用firstOrCreate。數據實際上得到持續使用這種方法。

$categories = [7, 12, 52, 77]; 
$tour = Tour::firstOrCreate($attributes)->cats()->sync($categories); 

必須確保的領域是大衆分配給能雖然使用firstOrCreate方法。因此,無論設置字段名在$可填寫的財產或者把這個巡迴賽模式:

protected $guarded = []; 
+0

不,對不起,這觸發了一個'未找到列:''where子句'中的1054個未知列'類別' - 這是我的問題的癥結所在;我是否需要首先從'$ attributes'數組中取消設置類別?正如我所說的,所有這些數據都捆綁到$ attributes中(這只是旅遊對象的作用,就像Laravel使用belongsToMany方法從數據庫中返回它一樣)-- – Inigo

+0

請按照旅遊中定義的關係模型 – trommelaap

+0

請參閱第二編輯 – Inigo

2

你需要定義你的旅遊模式$可填寫的屬性來告訴雄辯哪些屬性使用質量分配,因此會時要考慮默默地忽略類別相關的屬性。爲前。

<?php 
namespace App; 
use Illuminate\Database\Eloquent\Model; 

class Tour extends Model { 
    protected $fillable = ['name'] //... other attributes which are part of this model only and laravel will consider only these attributes and ignore category related attributes which you can consider later use. 
} 
+0

在這裏檢查https://laravel.com/docs/5.3/eloquent#mass-assignment –

+0

「它會默默地忽略與類別相關的屬性」不,我得到一個'未找到列:1054未知列'錯誤模型的數據庫表中的任何和所有不屬於列名稱的屬性。 – Inigo

+0

確保您的可填寫數組只包含可供瀏覽的列表 –

0

既然你提到的「CMS」和「從用戶後續的修改」,我猜你是從Form讓你的屬性,這意味着你得到一個Request對象/集合。
如果是這樣的話,那麼你可以嘗試

$tour = Tour::firstOrCreate($request->except('cats')); 
$categories = []; 
foreach($request->get('cats') as $key=>$value){ 
    $categories[] = $value; 
} 
$tour->cats()->sync($categories); 

但是,如果你$attributes我們構造一個數組(可能與表單數據的一些操作),按您的編輯那麼在這種情況下,您可以嘗試:

$tour = Tour::firstOrCreate(array_except($attributes, ['cats']); 
$categories = []; 
foreach($attributes['cats'] as $key=>$value){ 
    $categories[] = $value; 
} 
$tour->cats()->sync($categories); 

在任何情況下,你必須在你的模型,即Tour$fillable財產申報的質量分配領域。

希望這會有所幫助。