user2942945
user2942945

Reputation: 469

Laravel model attribute to not save in DB

I created a fake attribute inside my model that I need to use inside a created event.

The problem is since this fake attribute does not exist in my Database,I get a fatal error

<?php
class Occupancy extends Eloquent
{
    protected $table = 'occupancies';
    protected $fillable = array('component_id',
                                'title' , 
                                'supplier_conf_number' ,
                                'sub_product_code',
                                'occupancy',
                                'retail',
                                'cost',
                                'wholesale',
                                'pub',
                                'othertotal',
                                'othertotalB2B',
                                'index',
                                'nbpax',
                                'onrequest');

protected $isInsurance = false; // <-- this is my fake attribute

public static function boot()
    {
        if(_B2B && Auth::check() && !defined('_INSURANCE'))
        {
            $acc = Account::getAccount()->code;

            if($acc == "GVQ" || $acc == "VBG")
            {
                parent::boot();

                static::created(function($post) use ($acc)
                {
                    $booking = Booking::get_current_booking();

                    $ficav = 0;
                    $ficav = (($post->wholesale + $post->othertotalB2B) * 0.001);

                    if($acc == "GVQ" && Auth::user()->int_ext || ($booking && $booking->agent_ext != ""))
                        $ficav = 0;

                    $post->othertotalB2B += $ficav;
                    $post->othertotal += 0;
                    $post->save();
                });
            }
        }
    }
}

on creating event, only field in fillable should be inserted into the DB ?

Is there a way to have an attribute that will not be inserted into the DB ?

$occ = new Occupancy;
            $occ->component_id = $cid;
            $occ->index = 0;
            $occ->onrequest = false;

            $occ->title = $addon['name'];

            $occ->retail = 0;
            $occ->wholesale = $opt['prices']['total']['retail'];
            $occ->sub_product_code = 0;
            $occ->occupancy = 1;    
            $occ->cost = ($opt['prices']['total']['cost'] - $opt['prices']['total']['othertotal']);
            $occ->othertotal = $opt['prices']['total']['othertotal'];
            $occ->othertotalB2B = $opt['prices']['total']['othertotal'];        
            $occ->nbpax= count($param['names']);
            $occ->isInsurance = 1; // my fake attribute
            $occ->save(); // SQLSTATE[42S22]: Column not found: 1054 Unknown column 'isInsurance' in 'field list'

Upvotes: 1

Views: 6331

Answers (2)

T Bertie
T Bertie

Reputation: 31

I know this is an old topic but thought I'd share my approach in case it was useful for others.

The way I've done this is by defining the non-database attributes as protected, and then overriding the __get magic method for my additional attribute, as follows:

protected $_myVar;

public function __get( $property )
{
    switch($property)
    {
        case 'myVar':
            // Do what needs to be done to deliver the result
            return $this->_myVar;
        break;
        default:
            return parent::__get($property);
    }
}

I don't like declaring class variables as public because it breaks encapsulation. This has worked well for adding features to the User class without breaking the Authenticatable functionality. You can (and probably should) do similar to override __set to prevent the parent's magic method trying to set the value of a non-existent field in the database. But others may have a view on whether this is good or bad practice.

Upvotes: 0

Devon Bessemer
Devon Bessemer

Reputation: 35337

Make your property public. Protected and private properties cannot be accessed from outside of that class.

Since it is protected, $attributes['isInsurance'] is being set instead of $isInsurance when you assign it from this scope:

        $occ->isInsurance = 1; // my fake attribute

This is due to Eloquent's property overloading (__set method).

Upvotes: 7

Related Questions