简体   繁体   English

在Laravel中使用Eloquent进行更高级的数据库查询

[英]Using Eloquent in Laravel for more advanced DB queries

I've been developing a laravel application the last couple months and it's my first ride with the framework. 最近几个月我一直在开发laravel应用程序,这是我第一次使用该框架。 It's also my first time embracing and using an ORM (Eloquent). 这也是我第一次拥抱和使用ORM(雄辩)。

For the most part, Eloquent seems pretty straight forward when doing basic DB operations. 在大多数情况下,Eloquent在执行基本数据库操作时似乎很简单。 However when things get a little more complicated I often find myself spending way too much time trying to figure out how do it the Eloquent way and jump ship to raw db queries. 但是,当事情变得更加复杂时,我常常发现自己花了太多时间试图弄清楚如何用Eloquent方式跳转到原始数据库查询。

Was hoping someone might suggest whether or not my desired outcome in the more slightly complicated queries such as the one below should be achievable with Eloquent rather easily, or that I should just keep using raw DB queries. 希望有人建议我是否可以用Eloquent轻松实现我在较复杂的查询(例如下面的查询)中期望的结果,或者我应该继续使用原始DB查询。

Tables: products , users , alerts 表: 产品用户警报

alerts have a user_id , a product_id , and an amount at which the user would like to receive an alert that the product is on sale under a certain price. 提醒user_id ,一个product_idamount在该用户希望收到警报,该产品是销售在一定的价格。

Currently I'm using a raw db query to get all the alerts: 目前,我正在使用原始数据库查询来获取所有警报:

SELECT p.*, u.firstname, u.lastname, u.email, a.amount AS alert_amount
FROM alerts AS a                                       
JOIN dods AS d ON a.product_id = d.product_id                                        
JOIN products AS p ON d.product_id = p.id                                        
JOIN users AS u ON u.id = a.user_id
WHERE a.amount <= p.saleprice1

My eloquent models are set up with relations as follows 我雄辩的模型建立了如下的关系

User Model 用户模型

public function alerts()
{
    return $this->hasMany('Alert');
}

Product Model 产品型号

public function alerts()
{
    return $this->hasMany('Alert');
}

Alert Model 警报模型

public function product()
{
    return $this->belongsTo('Product');
}

public function user()
{
    return $this->belongsTo('User');
}    

Thanks for any and all suggestions. 感谢您提出的所有建议。 Matt 马特

To understand relationships, you need to understand where the reference should be on the tables. 要了解关系,您需要了解引用在表上的位置。

The alert model has a belongsTo() relationship with User that indicates the alerts table has a field named user_id (typically an unsigned int) that holds the related user id. 警报模型与User之间具有belongsTo()关系,指示alerts表具有一个名为user_id (通常为无符号int)的字段,其中包含相关的用户ID。

The user model has a hasMany() relationship with Alert that indicates the alert table holds the reference as per above. 用户模型与Alert具有hasMany()关系,该关系指示警报表包含上述引用。

One user has many alerts, a one to many relationship is established. 一个用户有许多警报,建立了一对多关系。

You can use this relationship with eloquent for any CRUD operation. 您可以雄辩地使用此关系进行任何CRUD操作。

Some examples to help you along 一些例子可以帮助你

To retrieve all alerts by user 按用户检索所有警报

$alerts = User::find(1)->alerts()->get();

To retrieve a user by alert 通过警报检索用户

$user = Alert::find(1)->user()->first();

To insert a new alert against a user 插入针对用户的新警报

$alert = new Alert(["name" => "alert1"]);

$user = User::find(1);

$user->alerts()->save($alert);

To delete all alerts associated with a user 删除与用户关联的所有警报

$user = User::find(1);

$user->alerts()->delete();

All you need is many to many relationship: 您需要的是多对多关系:

// User model
public function products()
{
   return $this->belongsToMany('Product')
     ->wherePivot('amount', '>=', DB::raw('products.salesprice1'))
     ->withPivot('amount');
}

// then
$user->products; // collection of products with price below alerts.amount

This actually ended up being the correct answer I was searching for (off the http://laravel.io/forum and thanks to @onecrush). 这实际上最终是我正在寻找的正确答案(在http://laravel.io/forum上,并感谢@onecrush)。

$alerts = Alert::with(['product','user'])->whereHas('product', function($q){
    $q->where('saleprice1', '<', DB::raw(alert.amount));
})->get();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM