Skip to main content
The AsCurrency cast converts currency code strings (e.g., "USD", "EUR") stored in your database to Currency objects in your Laravel models. This provides type safety and access to currency-related methods throughout your application.

How It Works

The cast automatically converts between strings and Currency objects:
  • Storage: Currency::of('USD')"USD" (stored as string)
  • Retrieval: "USD"Currency::of('USD') (Currency object)

Implementation

The AsCurrency class implements the CastsAttributes interface:
AsCurrency.php
public function get($model, string $key, mixed $value, array $attributes): Currency
{
    if (! is_string($value)) {
        throw new UnknownCurrencyException(__('brick-money::validation.unexpected_value', [
            'expected' => 'string',
            'actual' => gettype($value),
        ]));
    }

    return Currency::of($value);
}

public function set($model, string $key, mixed $value, array $attributes): string
{
    if (! $value instanceof Currency) {
        throw new UnknownCurrencyException(__('brick-money::validation.unexpected_value', [
            'expected' => Currency::class,
            'actual' => gettype($value),
        ]));
    }

    return $value->getCode();
}

Basic Usage

1

Define the cast in your model

use Devhammed\LaravelBrickMoney\Currency;
use Devhammed\LaravelBrickMoney\Casts\AsCurrency;
use Illuminate\Database\Eloquent\Model;

/**
 * @property Currency $currency
 */
class Product extends Model
{
    protected function casts(): array
    {
        return [
            'currency' => AsCurrency::class,
        ];
    }
}
2

Create database migration

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('currency', 3);  // ISO 4217 currency code
    $table->timestamps();
});
Use string('currency', 3) for standard ISO 4217 codes. For cryptocurrencies, you may need longer length like string('currency', 10).
3

Work with Currency objects

use Devhammed\LaravelBrickMoney\Currency;

// Create a product
$product = Product::create([
    'name' => 'Laptop',
    'currency' => Currency::of('USD'),
]);

// Database stores: "USD"

// Retrieve and use
$product = Product::find(1);
echo $product->currency->getName();           // "US Dollar"
echo $product->currency->getSymbol();         // "$"
echo $product->currency->getNumericCode();    // 840
echo $product->currency->getDecimalPlaces();  // 2

Use Cases

Use AsCurrency alongside money casts when you want both type-safe Money and Currency objects:
use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;
use Devhammed\LaravelBrickMoney\Casts\AsIntegerMoney;
use Devhammed\LaravelBrickMoney\Casts\AsCurrency;
use Illuminate\Database\Eloquent\Model;

/**
 * @property Money $price
 * @property Currency $currency
 */
class Product extends Model
{
    protected function casts(): array
    {
        return [
            'price' => AsIntegerMoney::of('currency'),
            'currency' => AsCurrency::class,
        ];
    }

    public function convertTo(Currency $targetCurrency, float $rate): Money
    {
        return $this->price->convertedTo($targetCurrency, $rate);
    }
}

Usage

$product = Product::find(1);

// Access currency information
echo $product->currency->getName();     // "US Dollar"
echo $product->currency->getSymbol();   // "$"

// Convert to another currency
$eur = Currency::of('EUR');
$convertedPrice = $product->convertTo($eur, 0.85);
echo $convertedPrice->format();         // "€84.99"

Available Currency Methods

Once cast to a Currency object, you have access to all currency information:
$currency = $product->currency;

// Basic information
$currency->getCode();            // "USD"
$currency->getName();            // "US Dollar"
$currency->getNumericCode();     // 840

// Formatting information
$currency->getSymbol();          // "$"
$currency->isSymbolFirst();      // true
$currency->isSymbolSpaced();     // false
$currency->getDecimalPlaces();   // 2
$currency->getDecimalSeparator(); // "."
$currency->getThousandPlaces();  // 3
$currency->getThousandSeparator(); // ","

// Comparison
$usd = Currency::of('USD');
$eur = Currency::of('EUR');
$currency->is($usd);             // true
$currency->is($eur);             // false

// Get underlying Brick\Money\Currency
$brickCurrency = $currency->getCurrency();

Querying by Currency

// Find all products in USD
$usdProducts = Product::where('currency', 'USD')->get();

// Find products in multiple currencies
$products = Product::whereIn('currency', ['USD', 'EUR', 'GBP'])->get();

// Group by currency
$currencyCounts = Product::select('currency', DB::raw('count(*) as count'))
    ->groupBy('currency')
    ->get();

foreach ($currencyCounts as $item) {
    echo "{$item->currency->getName()}: {$item->count}\n";
}

Validation

Validate currency codes in your requests:
use Devhammed\LaravelBrickMoney\Rules\CurrencyRule;
use Illuminate\Foundation\Http\FormRequest;

class CreateProductRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'currency' => [
                'required',
                'string',
                new CurrencyRule(),
            ],
        ];
    }
}

Complete Example

use Devhammed\LaravelBrickMoney\Money;
use Devhammed\LaravelBrickMoney\Currency;
use Devhammed\LaravelBrickMoney\Casts\AsIntegerMoney;
use Devhammed\LaravelBrickMoney\Casts\AsCurrency;
use Illuminate\Database\Eloquent\Model;

class Invoice extends Model
{
    protected function casts(): array
    {
        return [
            'amount' => AsIntegerMoney::of('currency'),
            'currency' => AsCurrency::class,
            'issued_at' => 'datetime',
        ];
    }

    public function convertTo(Currency $targetCurrency, float $rate): Money
    {
        return $this->amount->convertedTo($targetCurrency, $rate);
    }

    public function getFormattedAmount(): string
    {
        return $this->amount->format();
    }

    public function getCurrencyInfo(): array
    {
        return [
            'code' => $this->currency->getCode(),
            'name' => $this->currency->getName(),
            'symbol' => $this->currency->getSymbol(),
        ];
    }
}

Error Handling

The cast throws exceptions for invalid data:
use Brick\Money\Exception\UnknownCurrencyException;

try {
    $product = Product::create([
        'currency' => Currency::of('INVALID'),
    ]);
} catch (UnknownCurrencyException $e) {
    // Handle invalid currency code
}

try {
    $product->currency = 'Not a Currency object';
    $product->save();
} catch (UnknownCurrencyException $e) {
    // Handle invalid type (expected Currency object)
}

Best Practices

1

Use appropriate column length

// Standard currencies (ISO 4217)
$table->string('currency', 3);  // ✅ USD, EUR, GBP

// Cryptocurrencies
$table->string('currency', 10); // ✅ BTC, ETH, USDT
2

Add database indexes

$table->string('currency', 3)->index();
3

Combine with money casts

protected function casts(): array
{
    return [
        'price' => AsIntegerMoney::of('currency'),
        'currency' => AsCurrency::class,  // ✅ Type-safe access
    ];
}
4

Document property types

/**
 * @property Currency $currency ISO 4217 currency code
 */
class Product extends Model { }
5

Validate input

use Devhammed\LaravelBrickMoney\Rules\CurrencyRule;

public function rules(): array
{
    return [
        'currency' => ['required', new CurrencyRule()],
    ];
}

Benefits

Type Safety

Work with Currency objects instead of strings

Rich API

Access currency metadata and formatting rules

Validation

Automatic validation of currency codes

Integration

Works seamlessly with Money casts

Next Steps

AsIntegerMoney Cast

Store money in minor units (recommended)

Eloquent Overview

Back to Eloquent integration overview

Build docs developers (and LLMs) love