1

我是 Ruby on Rails 的新手。几个小时前开始学习 Ruby 和 Ruby on Rails,并尝试将它的 DRY 原则应用到我自己的 Laravel 代码中。

这就是我的 RoR 的样子:

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. 我怎样才能 DRYif(Wedding::find($id) === false)检查就像我的 RoR 代码?
  2. 如果Wedding::find($id) returns actual Wedding data,我怎样才能像$wedding variable在所有指定的方法中一样注入它?(如果可能,不要使用类范围寻找任何东西。)

非常感谢!

附言。对于不了解我的 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.)
4

2 回答 2

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

这称为 Route-Model 绑定。有关更多信息,请参阅http://laravel.com/docs/routing#route-model-binding

编辑

让我扩展这个例子,假设有一天你需要一个 url,/wedding/cahill-manley而不是/wedding/123,你可以删除该Route::model行,并在其位置添加:

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

然后事情继续进行。

于 2013-07-03T21:52:01.493 回答
0

您可以创建婚礼过滤器并将其应用于婚礼控制器:

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

我不知道你如何复制@wedding.destroy,但如果你想在整个地方注入一个变量,你可以View::share()app/filters.phpApp:before()中使用。

App::before(function($request)
{

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

});
于 2013-07-04T00:56:39.907 回答