Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save martindilling/d642c422f64a7d015abc to your computer and use it in GitHub Desktop.
Save martindilling/d642c422f64a7d015abc to your computer and use it in GitHub Desktop.
Polymorphic Coupons with Eloquent
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCouponsTable extends Migration
{
public function up()
{
Schema::create('coupons', function (Blueprint $table) {
$table->increments('id');
$table->string('type');
$table->string('code')->unique();
$table->integer('value')->nullable();
$table->integer('min_quantity')->nullable();
$table->timestamps();
});
}
public function down()
{
Schema::drop('coupons');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Coupon extends Model
{
protected $table = 'coupons';
public function __construct(array $attributes = [])
{
parent::__construct($attributes);
$this->type = static::class;
}
public static function findByCode($code)
{
$type = self::whereCode($code)->value('type');
return (new $type)->whereCode($code)->first();
}
}
<?php
use Illuminate\Database\Seeder;
class CouponSeeder extends Seeder
{
public function run()
{
\App\Coupon::create([
'code' => '001',
'value' => '0'
]);
\App\FixedValueCoupon::create([
'code' => 'AA1',
'value' => '1000'
]);
\App\PercentOffCoupon::create([
'code' => 'BB1',
'value' => '15'
]);
\App\MinimumQuantityCoupon::create([
'code' => 'CC1',
'value' => '15',
'min_quantity' => 2
]);
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class FixedValueCoupon extends Coupon
{
public function discount()
{
return 'Fixed value';
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class MinimumQuantityCoupon extends Coupon
{
public function discount()
{
return 'Minimum quantity';
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class PercentOffCoupon extends Coupon
{
public function discount()
{
return 'Percent off';
}
}
<?php
Route::get('/', function () {
$coupon = \App\Coupon::findByCode('001');
var_dump($coupon->toArray());
$fixedValue = \App\Coupon::findByCode('AA1');
var_dump($fixedValue->toArray());
$percentOff = \App\Coupon::findByCode('BB1');
var_dump($percentOff->toArray());
$minimumQuantity = \App\Coupon::findByCode('CC1');
var_dump($minimumQuantity->toArray());
});
@radel
Copy link

radel commented May 14, 2016

Found this Gist while watching Adam screencast, I like this approach and it's close to what I'm doing but your code is cleaner than mine! thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment