Developer | UX Advocate | T.J. Mahaffey - Alias Columns on Related Models in Laravel

0

Alias Columns on Related Models in Laravel

Our dev shop has most recently begun building a commerce-capable CMS in Laravel. This project has been a blast to work on and motivates me to work constantly to push the feature set forward quickly.

I've laid out the model relationships using Eloquent, of course, and that pattern follows most ecommerce applications in a general sense. I'd like to focus on the cart-to-orderitem relationship specifically for the sake of this article. In this project, a parent-child relationship exists between the Cart.php model and the Orderitem.php model. This relationship is created via Eloquent using the hasMany() method. Note the cart uses hasMany() and the order item uses the belongsTo() method. Both constructs are required for Eloquent to perform it's magic.

Cart.php


	class Cart extends Eloquent {
	
		protected $table = 'carts';
		protected $fillable = array();
		protected $guarded = array('id');
		
		public function user()
		{
			return $this->belongsTo('User');
		}
		
		public function orderitems()
		{
			return $this->hasMany('Orderitem');
		}
	}	

Orderitem.php


	class Orderitem extends Eloquent {
	
		protected $table = 'orderitems';
		protected $fillable = array('title', 'quantity', 'product_id', 'cart_id');
		protected $guarded = array('id');
		
		public function cart()
		{
			return $this->belongsTo('Cart');
		}
	
	}	

Now, once the above relationship was established and I was able to retrieve any given cart's order items, I began working up the cart's front-end view. There, I'd need to do some key calculations like totaling an order item's line-item subtotal. I could grab the quantity and price from the order item object and calculate that via Javascript when the view loads. However, I felt it would be more efficient and cleaner to have the database do that and send back the calculation right along with the other columns using a column alias in Eloquent.

To accomplish this, I made a quick guess on the syntax and tried this:


    public function orderitems()
    {
        return $this->hasMany('Orderitem')->select(['id', 'price', 'quantity', 'title', '(price * quantity) as itemTotal' ]);
    }

I quickly discovered, however, that my guess violated Eloquent's expectation that all values passed into the select() method would be strictly column names. So, I took another stab using Eloquent's now-beloved-by-me DB::raw() method to inject my alias syntax.


    public function orderitems()
    {
        return $this->hasMany('Orderitem')->select(['id', 'price', 'quantity', 'title', DB::raw('(price * quantity) as itemTotal') ]);
    }

This provided my front-end AJAX request an additional column called "itemTotal" on the response which I could present to the user as the order item's subtotal. The final Cart.php class looks like this:

Cart.php


	class Cart extends Eloquent {
	
		protected $table = 'carts';
		protected $fillable = array();
		protected $guarded = array('id');
		
		public function user()
		{
			return $this->belongsTo('User');
		}
		
		public function orderitems()
		{
                        return $this->hasMany('Orderitem')->select(['id', 'price', 'quantity', 'title', DB::raw('(price * quantity) as itemTotal') ]);
		}
	}	

Categories:Laravel, Eloquent

Comments: No comments yet

Be the first to comment

Post a comment

© 2024 T.J. Mahaffey