简体   繁体   中英

Laravel4 one-to-one relationship is not loaded when in testing environment

Im currently facing this strange behaviour.

<?php
// Models
class User extends \Eloquent {
    protected $table = 'user';
    public $timestamps = FALSE;

    public function credit() {
        return $this->hasOne('Credit', 'uid');
    }
}
class Credit extends \Eloquent {
    protected $table = 'user_credit';
    public $timestamps = FALSE;

    public function user() {
        return $this->belongsTo('User', 'uid');
    }
}

// Service
function doThings() {
    // This is always working 
    $credit = Credit::where('uid', $user->id)->first(); 
    // This doesn't work in test environment, but it does outside of it, i.e. in a route
    // $credit = $user->credit; 
    if (empty($credit)) {
        $credit = new Credit();
        // Set some fields... then save.
        $credit->foo = 'bar';
    }   
    $user->credit()->save($credit);
}

// Test
Service::doThings(); // <--- works as expected the first time
Service::doThings(); // <--- fails, trying to save a new record instead of updating.

// In a test route
Route::get('/test', function() {
    $user = User::find(1);
    Service::doThings(); // <--- works as expected
    Service::doThings(); // <--- works as expected
    Service::doThings(); // <--- works as expected
    return 'test';
});

Problem is that when accessing the credit model via the $user->credit, in the testing environment the model is not loaded and NULL is returned regardless the presence of the item inside the database.. It works when explicitly loaded, using Credit::find().

Outside the testing env, things works as expected.

Any hint?

In your class

class User extends \Eloquent {
    protected $table = 'user';
    public $timestamps = FALSE;

    public function credit() {
        return $this->hasOne('User', 'uid');
    }
}

You should use (to make a one to one relation between User <-> Credit using a custom key uid )

class User extends \Eloquent {
    protected $table = 'user';
    public $timestamps = FALSE;

    public function credit() {
        return $this->hasOne('Credit', 'uid'); // <---
    }
}

So, you can query like

$credit = User::find(1)->credit;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM