简体   繁体   中英

Unable to associate models without manually assigning the foreign key in Laravel 5

I'm running into an issue when trying to associate a child model to a parent in Laravel 5.

I see in the documentation under the Inserting Related Models 's "Associating Models (Belongs To)" section that I should be able to:

  • Create a child model instance: $comment = new Comment(['message' => 'A new comment.']);
  • Get the parent record: $post = Post::find(1);
  • Use the parent record's association method to save the child which should automatically relate it to the parent: $comment = $post->comments()->save($comment);

This makes sense to me conceptually, the problem I'm having is creating the child record without manually assigning the parent's id as a foreign key.

In my project, I have have a parent table Accounts and a child table Events . The Events schema has a foreign key constraint assigned for the Accounts id:

Schema::create('events', function(Blueprint $table)
{
    $table->increments('id');
    $table->integer('account_id')->unsigned();
    $table->foreign('account_id')->references('id')->on('accounts');
    $table->timestamp('date_of_donation');
    $table->timestamp('date_last_donation_letter_sent');
    $table->timestamps();
});

So when I go to create the Events instance that I'm planning on associating to the parent Accounts I get an exception thrown:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'account_id' cannot be null (SQL: insert into events ( date_of_donation , date_last_donation_letter_sent , account_id , updated_at , created_at ) values (2015-05-16, , , 2015-05-16 17:35:36, 2015-05-16 17:35:36))

I understand why the error is thrown because I'm not giving the Events instance a foreign key value.

I can get around it by getting the Accounts record first and creating the Events instance like so:

$account = $accounts->findOrFail($id);
$event = $events->create(['account_id' => $account->id, ...]);

But it seems like the whole point of the "Associating Models (Belongs To)" section is so that you don't have to do this.

Am I missing or misunderstanding something about how the associating functionality is supposed to work?

Update

Here's my Account model:

<?php namespace Hub;

use Illuminate\Database\Eloquent\Model;

class Account extends Model {

    protected $fillable =[
        'first_name',
        'last_name',
        'display_name',
        'email',
        'zipcode',
        'phone_number'
    ];

    public function donationEvents(){
        return $this->hasMany('Hub\donationEvent');
    }


}

And my Event model:

<?php namespace Hub;

use Illuminate\Database\Eloquent\Model;

class Event extends Model {

    protected $fillable = [
        'account_id',
        'date_of_donation',
        'date_last_donation_letter_sent'
    ];

    public function donationItems(){
        return $this->hasMany('Hub\DonationItem');
    }

    public function account(){
        return $this->belongsTo('Hub\Account');
    }
}

Also, here's the code that triggers the error:

Route::get('dev2', function ( Hub\Account $accounts, Hub\Event $events){
    $account = $accounts->findOrFail(1);

    // This is where I'm trying to create the child record but I get the exception
    $event = $events->create(['date_of_donation' => '2015-05-16', 'date_of_last_donation_letter_sent' => '']);

    $event = $account->events()->save($event);
    return [$account, $event];

});

The thing is, create() instantiates a new model and directly saves it. So you actually save it twice. However the first time there is no foreign key set.

Instead of create() use fill() to set all the values without saving:

$event = $events->fill(['date_of_donation' => '2015-05-16', 'date_of_last_donation_letter_sent' => '']);

Or you can use the constructor as well (I personally prefer this solution)

$event = new Event(['date_of_donation' => '2015-05-16', 'date_of_last_donation_letter_sent' => '']);

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