2013-07-03 21 views
1

我對Ruby on Rails非常新手。就在幾個小時前開始學習Ruby和Ruby on Rails,並試圖將其DRY原則應用到我自己的Laravel代碼中。Laravel是否具有Rails的before_filters將變量綁定到控制器方法中?

這是我的回報率看起來像:

class WeddingController < ApplicationController 

    before_filter :get_wedding 

    def get_wedding 
     /* 
      If Wedding.find(2) returns false, redirect homepage 
      Else, bind @wedding into all methods for use 
     */ 
    end 

    def edit 
     @wedding //this method has access to @wedding, which contains Wedding.find(2) data. 
    end 

    def update 
     //Same as above method 
    end 

    def destroy 
     //Same as above method, can do things like @wedding.destroy 
    end 
end 

這是我Laravel看起來像

class Wedding_Controller extends Base_Controller { 

public function edit($id) 
{ 
    if(Wedding::find($id) === false) 
     return Redirect::to('/); 

    //Edit code 
} 

public function update($id) 
{ 
    if(Wedding::find($id) === false) 
     return Redirect::to('/); 

    //Update code 
} 

public function destroy($id) 
{ 
    if(Wedding::find($id) === false) 
     return Redirect::to('/); 

    //Destroy code 
} 
} 
  1. 我怎麼可以幹if(Wedding::find($id) === false)檢查,像我RoR的代碼?
  2. 如果Wedding::find($id) returns actual Wedding data,我如何在所有指定的方法中將它注入爲$wedding variable? (如果可能的話,不要尋找任何使用類範圍的東西。)

非常感謝!

Ps。對於不瞭解我的RoR腳本的人員;基本上它是這樣做的。

Before any method call on this controller, execute get_wedding method first. 
If get_wedding can't find the wedding in database, let it redirect to homepage. 
If get_wedding finds the wedding in database, inject returned value as @wedding variable to all methods so they can make use of it. (e.g destroy method calling @wedding.destroy() directly.) 

回答

2

是的,過濾器可以處理傳遞給路由的數據。例如:

Route::filter('wedding', function($route, $request) { 
    $id = $route->getParameter('id'); 
    $wedding = Wedding::findOrFail($id); // if no wedding is found, it returns a 404 here 
    // Here is where we hit a small road block. You can call 
    $route->setParameters(array($wedding)); 
    // But you just erased any other parameters the route was accepting. 
    // So then you start getting *all* the parameters 
    $params = $route->getParameters(); 
    // Then you try to merge your data in somehow, then you set it back, etc. 
}); 

有一種更簡單的方法!

從你的控制器的結構,我假設它是一個資源控制器。以下例子:

Route::model('wedding, 'Wedding'); // varname, model name 
Route::resource('wedding', 'WeddingController'); // The first param here matches the first param above. 

class WeddingController extends BaseController { 
    ... 
    public function show(Wedding $wedding) { 
     return View::make('wedding')->with('wedding', $wedding); 
    } 
    ... 
} 

這叫做路由模型綁定。欲瞭解更多信息,請參閱http://laravel.com/docs/routing#route-model-binding

編輯

讓我在這個例子擴大,說有一天你需要有一個像/wedding/cahill-manley代替/wedding/123一個網址,你可以刪除Route::model線,並在其位置加:

Route::bind('wedding', function($value) { 
    return Wedding::where('slug', $value)->firstOrFail(); 
}); 

然後事情繼續工作。

+0

我不是Laravel的專家,所以我不知道我的控制器是否是資源控制器。我會打穀歌,看看是什麼資源控制器。不熟悉條款。 – Aristona

+0

如果你使用'Route :: resource'函數,它是一個資源控制器。請參閱http://laravel.com/docs/controllers#resource-controllers –

+0

不,我所有的方法調用都是直接調用。喜歡; Route :: get('something/{id}','SomethingController @ show'); – Aristona

0

您可以創建過濾器的婚禮,並把它應用到婚禮控制器:

public function __construct() 
{ 
    $this->beforeFilter('wedding'); 
} 

我不知道你怎麼能複製@ wedding.destroy,但如果你想在所有注入的變量您可以使用位於app/filters.phpApp:before()中的View::share()

App::before(function($request) 
{ 

    $check_wedding = Wedding::where('...'); 
    if($check_wedding) 
    { 
     View::share('wedding', $check_wedding); 
    } 
    else 
    { 
     return Redirect::to('/'); 
    } 

}); 
+0

查看::共享只有共享視圖文件的變量。我需要在控制器中完成。 – Aristona

+0

是的,我很抱歉Imaqtpie先生。如果我將View :: share更改爲Config :: set,則Config :: get('wedding')將在所有控制器中可用。我希望有人展示如何在任何地方都可以買到婚禮,因爲我也很感興趣。 – user2094178

相關問題