模型/控制器变量 - Laravel

Pan*_*ply 1 php eloquent laravel-4

我一直在我的控制器中使用Query构建器,但是想要使用eloquent和query builder.我想知道在两者之间传递变量的最佳实践.我已经通过文档但仍然遇到问题.

以下是我在控制器中执行操作的方法:

public function getRetailers($city) {    
    $locations = DB::table('retailers_listings')
        ->orderBy('country', 'asc')
        ->Where('city', $city)
        ->get();

        $this->layout->header = $city;
    $content = View::make('retailers.stores')
        ->with('header', $this->layout->header)
        ->with('store_listings', $locations)

        if (Request::header('X-PJAX')) {
        return $content;
        } else { 
            $this->layout->content = $content; 
        } 
    }
Run Code Online (Sandbox Code Playgroud)

我如何以雄辩和模特的方式完成上述工作?如何从视图中将变量$ city传递给模型.更深入的建议然后文档给我的将是伟大的.

tli*_*kos 5

将模型作为控制器中的依赖项注入.

在该示例中,为了简单起见,我参考列表模型.

class HomeController extends BaseController {

    protected $listing;

    // Type hint your model. This is laravels automatic resolution

    // It will automatically inject this dependency for you

    public function __construct(Listing $listing) 
    {
        $this->listing= $listing;
    }

    public function index()
    {
        $listings = $this->listing->whereTitle(Input::get['title'])->get();

        return View::make('listing' , compact($listings));
    }

}
Run Code Online (Sandbox Code Playgroud)

更好的方法是使用可以交换存储实现的存储库.

有关详细信息,请查看此帖子中的答案.

事实上,您可以在控制器中使用Listing模型,而不需要依赖注入

Listing::all();
Run Code Online (Sandbox Code Playgroud)

但前面提到的方法使它更清晰一些.

UPDATE

我不确切知道你的应用程序的结构,所以我会尝试模仿.您可以更改文件和类名以匹配您的实现.

准备步骤

  1. 在您的app文件夹下,创建一个名为Acme的新文件夹(或任何您喜欢的文件夹).此文件夹与控制器,模型,视图等处于同一级别.
  2. 在Acme文件夹内创建另一个名为Repositories的文件夹
  3. 在Repositories文件夹中,创建一个名为RetailerRepository.php的新文件
  4. 编辑根目录中的composer.json文件并添加prs-0部分,以便自动加载我们的新闻类

    "autoload": {
    "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/tests/TestCase.php" ], "psr-0": { Acme": "app/Acme" } }

  5. 在你的控制台运行中composer dumpautoload -o,你就完成了

现在让我们做一些代码

我假设你的ORM是

class Retailer extends Eloquent{}
Run Code Online (Sandbox Code Playgroud)

编辑您的Acme/Repositories/RetailerRepository.php如下所示:

<?php namespace Acme/Repositories

use Retailer;

class RetailerRepository {

  public function getLocations($city) {

    return Retailer::whereCity($city)->orderBy(‘country’, ‘asc’)->get();

  }    
}
Run Code Online (Sandbox Code Playgroud)

编辑您的控制器看起来像这样.我使用通用名称,但您可以切换到您自己的名称.

<?php

use Acme/Repositories/RetailerRepository;

class RetailersController extends BaseController {

  protected $repo;

  public function __construct(RetailerReposiroty $repo) {

    $this->repo = $repo;
  }

  public function index($city) {

    // I assume that the route is 

    // Route::get('retailers/{city}','RetailersController@index')

    $locations = $this->repo->getLocations($city);

    // I keep it simple here but you can do whatever you want

    return View::make('retailers.stores')->with('stores', $locations);
  }

}
Run Code Online (Sandbox Code Playgroud)

正如您现在所看到的,您的控制器不知道数据来自哪里,但它知道如何访问它.它不必知道您的数据在MySQL中可用.知道某处可用,这很好.此外,通过这种方式构建您的应用程序,现在您可以使用任何您喜欢的控制器中的存储库功能,只需将存储库注入构造函数中的依赖项即可.在复杂的应用程序中,您可能会使用RetailerRepositoryInterface和多个具体实现,但让我们在这里保持简单.

现在,是否要求您的应用程序提供例如计费功能.在Acme下创建一个名为Services的新文件夹,并在那里定义您的服务提供者.不要使用业务逻辑使控制器膨胀.构建您的Acme文件夹,但您希望满足您的需求.这是你的应用程序!

有一种常见的误解,即模型只是一个类(例如,在我们的案例中扩展Eloquent的Retailer类).这种误解以及"Fat models skinny controllers"这一表达方式已经导致许多人认为他们必须从控制器中获取所有业务逻辑(绝对正确)并将其放在一个简单的类中(这绝对是错误的).

你的模型(MVC中的M)它不仅仅是一个类.它是一个包含域实体,数据抽象,服务提供商等的层.

希望我帮忙.