從您的代碼中,您定義的關係是相反的順序。
我的意思是在邏輯上,一個Tour
有一個FeaturedImage
和FeaturedImage
屬於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);
}
希望這有助於。
[Call to undefined method Illuminate \ Database \ Query \ Builder :: associate()]可能重複(http://stackoverflow.com/questions/19868838/call-to-undefined-method-illuminate-database-query -builderassociate) – Froxz
我已經通過這個話題,我發佈了這個。 –