0
votes

I've been developing a laravel application the last couple months and it's my first ride with the framework. It's also my first time embracing and using an ORM (Eloquent).

For the most part, Eloquent seems pretty straight forward when doing basic DB operations. 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.

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.

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.

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

3

3 Answers

0
votes

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.

The user model has a hasMany() relationship with Alert that indicates the alert table holds the reference as per above.

One user has many alerts, a one to many relationship is established.

You can use this relationship with eloquent for any CRUD operation.

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();
0
votes

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
0
votes

This actually ended up being the correct answer I was searching for (off the http://laravel.io/forum and thanks to @onecrush).

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