2016-12-16 55 views
0

我有2個表是在一對一的關係:插入到兩個表是一對一的關係嗎laravel

之旅:

id|title|content 

featured_image:

id|tour_id|name|path 

我型號FeaturedImage.php

class FeaturedImage extends Model 
{ 
public function tour() 
{ 
    return $this->hasOne('App\Tour'); 
} 
} 

Tour.php

class Tour extends Model 
{ 
    public function featuredimage() 
    { 
    return $this->belongsTo('App\FeaturedImage'); 
    } 
} 

我要救tour_idfeatured_image表創建旅遊時。我使用相同的表格填寫tours表格並上傳featured_image

這是我店裏的方法是這樣的:

public function store(Request $request) 
{ 

    //validate the date 
    $this->validate($request, [ 
      'title' => 'required|max:255', 
      'content' => 'required' 
     ]); 
    //store the date 
    $tour = new Tour; 

    $tour->title = $request->title; 
    $tour->content = $request->trip_code; 

    $tour->save(); 

    $featured_image= new FeaturedImage; 
    // save featured_image 
    if($request->hasFile('featured_image')){ 
     $image = $request->file('featured_image'); 
     $filename = $image->getClientOriginalName(); 
     $location = public_path('images/featured_image/'.$filename); 
     Image::make($image)->resize(800, 600)->save($location); 

    $featured_image->path= $location; 
    $featured_image->tour()->associate($tour); 
    $featured_image->save(); 
    } 

    //redirect to 
    Session::flash('success','Tour is successfully created !'); 
    return redirect()->route('tours.show',$tour->id); 
} 

我成功的數據保存到tours表,但無法在featured_image表保存。我得到這個錯誤:

Call to undefined method Illuminate\Database\Query\Builder::associate() 

我會很感激,如果有人可以幫助我。

+0

[Call to undefined method Illuminate \ Database \ Query \ Builder :: associate()]可能重複(http://stackoverflow.com/questions/19868838/call-to-undefined-method-illuminate-database-query -builderassociate) – Froxz

+0

我已經通過這個話題,我發佈了這個。 –

回答

2

可以用戶Mass Assignment創建條目分爲DB這樣的:

$this->validate(request()->all(), [ 
    'title' => 'required|max:255', 
    'content' => 'required' 
]); 

$tour_inputs = array_only(
    $tour_inputs. 
    [ 
     'title', 
     'content', 
    ] 
); 

$tour = Tour::create($tour_inputs); 

if($request->hasFile('featured_image')) { 
    $image = $request->file('featured_image'); 
    $filename = $image->getClientOriginalName(); 
    $location = public_path('images/featured_image/'.$filename); 
    Image::make($image)->resize(800, 600)->save($location); 

    $featuredImage = $tour->featuredImage()->save(new FeaturedImage([ 
     'name' => $filename, 
     'path' => $location, 
    ])); 
} 

Remember to define the $fillables inside your models, your models should look like this,

do check your relations, that you've made in the models, according to me they aren't correct:

class Tour extends Model 
{ 
    protected $fillables = [ 
     'title', 
     'content', 
    ]; 

    public function featuredImage() 
    { 
     return $this->hasOne('App\FeaturedImage'); 
    } 
} 


class FeaturedImage extends Model 
{ 
    protected $fillables = [ 
     'name', 
     'path', 
     'tour_id', 
    ]; 

    public function tour() 
    { 
     return $this->belongsTo('App\Tour'); 
    } 
} 

希望這有助於!

+0

我剛剛在'FeaturedImage.php'中添加了可用的文件,這是正確的嗎? 'protected $ fillable = ['tour_id','path','name'];' –

+0

查看我更新的答案! –

0

從您的代碼中,您定義的關係是相反的順序。

我的意思是在邏輯上,一個Tour有一個FeaturedImageFeaturedImage屬於Tour

class Tour extends Model 
{ 
    //Mass Assignable fields for the model. 
    $fillable = ['title', 'content']; 

    public function featuredimage() 
    { 
     return $this->hasOne('App\FeaturedImage'); 
    } 
} 

class FeaturedImage extends Model 
{ 

    //Mass Assignable fields for the model 
    $fillable = ['tour_id', 'name', 'path']; 

    public function tour() 
    { 
     return $this->belongsTo('App\Tour'); 
    } 
} 

然後在你的控制器

public function store(Request $request) 
{ 

    //validate the data 
    $this->validate($request, [ 
     'title' => 'required|max:255', 
     'content' => 'required' 
    ]); 
    //store the data 

    $tour = Tour::firstOrCreate([ //protection against duplicate entry 
     'title' => $request->get('title'), 
     'content' => $request->get('trip_code') 
    ]); 


    if($tour) //if the Tour exists then continue 
    {   
     // save featured_image 
     if($request->hasFile('featured_image')){ 
      $image = $request->file('featured_image'); 
      $filename = $image->getClientOriginalName(); 
      $location = public_path('images/featured_image/'.$filename); 
      Image::make($image)->resize(800, 600)->save($location); 

      $featured_image = $tour->featuredimage()->create([ 
       'path' => $location, 
       'name' => $filename //if you have this field on your FeaturedImage   
     } 
     //you could also have an else block to redirect back if the input doesn't have a file 


     //redirect to 
     Session::flash('success','Tour is successfully created !'); 
     return redirect()->route('tours.show',$tour->id); 
    } 
    else 
    { 
     //if there occurs any error display the error message and redirect back - probably with validation errors or exception errors 
     Session::flash('error','Error message'); 
     return redirect()->back()->withInput()->withErrors(); 
    } 

} 

而且不要忘了向大衆分配字段添加到$fillable陣列上您的模型。

UPDATE

當一個單一的表單提交包含多個表的數據庫事務的情況下,你應該使用try{}catch{}確保要麼所有的關聯交易沒有任何問題,運行或者沒有交易的經歷 - 要避免數據差異。

你可以重寫你的控制器代碼

public function store(Request $request) 
{ 

    //validate the data 
    $this->validate($request, [ 
     'title' => 'required|max:255', 
     'content' => 'required' 
    ]); 
    //store the data 

    //use the DB::beginTransaction() to manually control the transaction 
    //You would ideally want to persist the data to the database only if the input provided by the user 
    //has valid inputs for Tour as well as FeaturedImage, in case if any one invalid input you do not 
    //want to persist the data 
    DB::beginTransaction(); 

    try 
    { 
     //firstOrCreate gives protection against duplicate entry for tour with same title and content 
     $tour = Tour::firstOrCreate([ 
      'title' => $request->get('title'), 
      'content' => $request->get('trip_code') 
     ]); 

     //proceed further only if $tour exists 
     if($tour) 
     {   
      // get featured_image 
      if($request->hasFile('featured_image')){ 
       $image = $request->file('featured_image'); 
       $filename = $image->getClientOriginalName(); 
       $location = public_path('images/featured_image/'.$filename); 
       Image::make($image)->resize(800, 600)->save($location); 

      //save the featured_image 
       $featured_image = $tour->featuredimage()->create([ 
        'path' => $location, 
        'name' => $filename //if you have this field on your FeaturedImage   
      } 

     } 
    } 
    catch(\ValidationException $e) 
    { 
     //In case of validation error, rollback the database transactions to avoid data discrepancy. 
     DB::rollBack(); 

     $errors = $e->getMessage(); 
     Session::flash('error', 'Whoops.. Please check the provided inputs'); 
     return redirect()->back()->withInput()->withErrors['errors', $errors]; 
    } 
    catch(\Exception $e) 
    { 
     //In case of any other error, rollback the database transactions to avoid data discrepancy. 
     DB::rollBack(); 

     $errors = $e->getMessage(); 
     Session::flash('error', 'Whoops.. Something went wrong. Please try again'); 
     return redirect()->back()->withInput()->withErrors['errors', $errors]; 
    } 

    //If both the transactions to the database i.e. saving the Tour as well as FeaturedImage ran without problem 
    //Commit to the database 
    DB::commit(); 

    //redirect to 
    Session::flash('success','Tour is successfully created !'); 
    return redirect()->route('tours.show',$tour->id); 

} 

希望這有助於。

相關問題