Laravel上的不稳定附加功能

I have a Flair and a Link model, also I've created a migration named 'flair_link' to keep a relation between the two. Because Link can be flairable or not based on their Category which is also an another model.

This is my migration file for create_flair_linl_table:

Schema::create('flair_link', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('link_id')->unsigned();
    $table->foreign('link_id')->references('id')->on('links');
    $table->integer('flair_id')->unsigned();
    $table->foreign('flair_id')->references('id')->on('flairs');
    $table->timestamps();
});

On the LinkController.php under new() function:

public function makeLink(Request $request){

    $request->validate([
        'title' => 'required',
        'url' => 'required|url',
        'category_id' => 'required|numeric'
    ]);

    $link = new Link;
    $link->title = $request->title;
    $link->url = $request->url;
    $link->user_id = Auth::id();
    $link->category_id = $request->category_id;
    if($request->flair) {
        // $link->attachFlair((int)$request->flair);
        // or
        $link->flairs()->attach(Flair::where('id', (int)$request->flair)->firstOrFail());
    };
    if( $link->save() ){
        return redirect()->route('link.show', [ 'id' => $link->id ]);
    }
}

Although when I use tinker to create relation between $link and $flair somehow it works weirdly:

$link = App\Link::find(1)
$flair = App\Flair::find(1)
$link->flairs()->attach($flair)

returns: null but when I check $link->flairs I can see that the flair is succesfully attached to the link.

Yet when I make the form like this:

<select name="flair">
    @foreach ($category->flairs as $flair)
        <option value="{{ $flair->id }}">{{ $flair->name}}</option>
    @endforeach
</select>

This is what I get:

SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: flair_link.link_id (SQL: insert into "flair_link" ("flair_id", "link_id") values (1, ))

I found my mistake. In order for the attach function to work we need the model. I was calling the attach method before I saved the link. The solution is :

if( $link->save() ){
    if($request->flair) {
        $link->attachFlair((int)$request->flair);
        // or
        // $link->flairs()->attach(Flair::where('id', (int)$request->flair)->firstOrFail());
    };
    return redirect()->route('link.show', [ 'id' => $link->id ]);
}