0

我有users一张orders桌子。一个用户可以有多个订单,一个订单属于一个用户。

Users
id | name | email

Orders
id | user_id | name

所以我的用户模型如下:

class User extends Eloquent{
    public function orders(){
        return $this->hasMany('Order', 'user_id');
   }
}

我的订单型号:

class Order extends Eloquent{
    public function user(){
         return $this->belongsTo('User', 'user_id');
   }
}

现在,我有一个订单控制器,它将列出数据库中的订单。我想根据 GET 变量列出订单。

例如:www.domain.com/order?user=some+name
www.domain.com/order?name=order+name

对于第二个,我可以执行以下操作:

$orders = Order::with('user')->where('name', 'LIKE', '%'.Input::get('name') . '%')->get();

但对于第一个,以下代码失败:

$orders = Order::with('user')->where('user.name', 'LIKE', '%' . Input::get('user') . '%')->get();

我也试过这个:

$orders = Order::with(array('user' => function($q){
    $q->where('name', 'LIKE', '%' . Input::get('user') . '%');
   }))->get();

无论用户名是否与 GET 字符串匹配,此命令都会返回所有订单。

那么,有没有办法让我能做到以上几点呢?手动加入是唯一的方法吗?

4

3 回答 3

2

基于提问者评论的编辑:话虽如此,您可能需要根据过滤器/搜索访问多个表字段。这是实现它的一种方法。

在您的 Order.php 模型中,执行以下操作:

public function scopeOrdersByQuery($query, $userName, $orderName)
{
    $query->leftJoin('users', 'users.id', '=', 'orders.user_id')
        ->select(array('orders.*', DB::raw('users.name as user_name'), DB::raw('users.id as uid')));

    if (!empty($userName))
    {
       $query = $query->whereIn('users.user_name', $userName);
    }

    if (!empty($orderName))
    {
       $query = $query->whereIn('orders.name', $orderName);
    }
}

根据需要添加更多表连接。

在您的 OrdersController 中执行以下操作:

$userName = Input::get('userName');
$orderName = Input::get('orderName');

$orders = Order::ordersByQuery($userName, $orderName)->get();

现在,您可以显示所有订单或基于多个查询或仅一个查询进行搜索。未经测试,但应该可以工作。

- - - - - - 编辑 - - - - - -

如果您希望获取特定用户的所有订单,我会使用用户 ID。

在您的 Order.php 模型中,执行以下操作:

public static function getOrdersByUserId($userId)
{
    $orders = Order::with('user')->whereIn('user_id', $userId)->get();

    return $orders;
}

然后,您可以通过在 OrdersController 中执行此操作将此方法传递给您所追求的特定用户 ID:

$userId = Input::get('user');

$orders = Order::getOrdersByUserId($userId);

现在,这是假设在您的视图中,您正在将用户 ID 添加到名为“用户”的输入的值中。

您还可以通过在 Orders.php 模型中使用范围方法来扩展 getOrdersByUserId() 方法以容纳空白 $userId 值,如下所示:

public function scopeGetOrdersByUserId($query, $userId)
{
    $query->with('user');

    if(!empty($userId))
    {
        $query = $query->whereIn('user_id', $userId);
    }
}

现在在您的控制器中,执行以下操作:

$userId = Input::get('user');

$orders = Order::getOrdersByUserId($userId)->get();
// if paginating do $orders = Order::getOrdersByUserId($userId)->paginate(10);

这样做将允许您在 OrdersController 的 index 方法中使用此代码,从而允许您在提供 id 时显示所有订单或特定用户订单。

编辑:我忘记提及的一件事是,在生成表单时,在控制器中执行以下操作:

$users = User::orderBy('name')->lists('name', 'id');

然后将此变量传递给您的视图并使用它来填充您的用户选择框。我假设您正在使用选择框来选择用户。

编辑:正如@GladToHelp 所指出的,您可能希望使用急切负载约束向急切加载的模型添加约束。您可以通过修改 Orders.php 模型中的 getOrdersByUserId() 范围方法来使用用户名来做到这一点:

public function scopeGetOrdersByUserName($query, $userName)
{
    $query->with(array('user' => function($query2)
    {
        $query2->where('name', 'like', '%$userName%');
    }));
}

注意:这是未经测试的代码。

也就是说,您可能只想简单地使用:

$user = User::with('orders')->where('name', $name)->get();

然后在 $user->orders 的视图中使用 foreach 循环。

于 2013-10-01T13:19:44.807 回答
1

这是最接近您需要的:扩展模型

 public function newQuery($excludeDeleted = true){
        return parent::newQuery()->join('table','field1','=','field2');
    }

更多信息在这里: http: //forums.laravel.io/viewtopic.php?pid=56659#p56659

于 2013-10-01T13:14:07.207 回答
0

所以我最终使用 JOINS 如下:

$orders = Order::with('user')
             ->join('users', 'users.id', '=', 'orders.user_id')
             ->where('users.name', 'LIKE', '%' . Input::get('name') . '%')->get();

上面的例子看起来不错,因为我只加入了两个模型/表。但是在我的实际应用程序中,我有 5 个模型,我用 Order 急切地加载,它确实让人感到困惑,表列名称冲突等等。

希望在 Eloquent 中有一种更简单的方法。

于 2013-10-01T13:57:57.263 回答