2016-12-16 4 views
0

二つのテーブルに挿入します。私は1対1の関係にある2つのテーブル持って一対一relationslip 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'); 
    } 
} 

私はツアーが作成されたときにfeatured_image表にtour_idを保存したいです。私は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

[定義されていないメソッドを呼び出す\ 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'にfillableを追加しました。これは正しいですか? 'protected $ fillable = ['tour_id'、 'path'、 'name'];' –

+0

私の更新された答えを見てください! –

0

コードから、定義した関係は逆の順序になります。

つまり、論理的には、Tourは、FeaturedImageFeaturedImageの1つが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配列に質量割り当て可能フィールドを追加することを忘れないでくださいインチに - 単一のフォームの提出は複数のテーブルでデータベーストランザクションが含まれ、すべての関連の取引のいずれかが何らかの問題なく実行したり、取引のいずれもが通過することを確実にするためにtry{}catch{}を使用する必要がある場合については

UPDATE

データの不一致を避ける。あなたは

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); 

} 

としてあなたのコントローラのコードを書き換えることができ

は、この情報がお役に立てば幸いです。

関連する問題