Laravel 4雄辩的约束

Web新手

我有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');
   }
}

现在,我有了一个Order控制器,它将列出数据库中的订单。我想根据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字符串匹配,此命令都会返回所有订单。

因此,我能否雄辩地实现上述目标?手动加入是唯一的方法吗?

加雷斯·戴恩(Gareth Daine)

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

在您的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添加到名为“ user”的输入的值中。

您还可以通过在Orders.php模型中使用scope方法来扩展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循环。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章