Francisunoxx Francisunoxx - 4 months ago 7
PHP Question

Using associate() method won't work (BadMethodCallException)

I'm trying to

associate
my Document model current id from view using Comment model. But after hitting the button. It always says.


Call to undefined method Illuminate\Database\Query\Builder::associate()


CommentController

class CommentController extends Controller
{

public function postComments(Request $request, Document $document)
{

$this->validate($request,
[
'comment' => 'required',
]);

$document = Document::find($document);

$commentObject = new Comment();

$commentObject->comment = $request->comment;
$commentObject->associate($document);
$commentObject->save();

return redirect()->back();
}
}


I'm trying here to get the current
id
of the model from view so I can associate this in my
$commentObject
.

DocumentController

//READ
public function readDocuments($id)
{
//Find the document in the database and save as var.
$document = Document::find($id);

return view ('document.read')->with('document', $document);
}


routes

Route::get('/document/{id}',
[
'uses' => '\App\Http\Controllers\DocumentController@readDocuments',
'as' => 'document.read',
'middleware' => 'auth',
]);


This is where I get the current id of the view.

//COMMENT
Route::post('/document/{document}/comments',
[
'uses' => '\App\Http\Controllers\CommentController@postComments',
'as' => 'comments',
]);


View

<div class = "col-md-6">

<div class = "form-group">

<textarea id = "content">{{ $document->content }}</textarea>

</div>

<div class = "form-group">

<button type = "submit" class = "btn btn-success">Approve</button>

</div>
</div>

<!--COMMENT CONTROLLER-->
<div class = "col-md-6">
<form class = "form-vertical" method = "post" action = "{{ url('/document/'.$document->id.'/comments') }}">

<div class = "form-group {{ $errors->has('comment') ? ' has-error' : '' }}">

<label for = "comment">Comment:</label>
<textarea class = "form-control" rows = "4" id = "comment" name = "comment" placeholder = "Leave a feedback"></textarea>

@if ($errors->has('comment'))
<span class = "help-block">{{ $errors->first('comment') }}</span>
@endif

</div>

<div class = "form-group">

<button type = "submit" class = "btn btn-primary">Comment</button>

</div>

<input type = "hidden" name = "_token" value = "{{ Session::token() }}">

</form>
</div>


I think I'm having a error in my CommentController because when I tried to save or insert. I think it cannot get the current id of the model. Any help or tips? Thanks!

Update

Models:

Comment

class Comment extends Model
{
protected $tables = 'comments';

protected $fillable =
[
'comment',
'document_id',
];

public function documents()
{
return $this->belongsTo('App\Models\Document');
}
}


Document

class Document extends Model
{

protected $table = 'documents';

protected $fillable =
[
'title',
'content',
'category_id',
];

public function comments()
{
return $this->hasMany('App\Models\Comment');
}
}

Answer

The associate() method is supposed to be applied on relations.

I believe (considering you Comment Model has documents relation), you should use

$commentObject->documents()->associate($document);

Furthermore, I believe your method should be as follows..

public function postComments(Request $request, Document $document)
{

    $this->validate($request,
    [
        'comment' => 'required',
    ]);

    //No need to do the following - Laravel 5.2 will Model Bind it because of Document $document in parameters above
    //$document = Document::find($document);

    $commentObject = new Comment();

    $commentObject->comment = $request->comment;

    $document->comments()->save($commentObject);
    //..other tasks


    return redirect()->back();
}

$document->comments() is a query builder and when you pass it the ->save($comment) , it updates the $comment object's document_id property and sets it to the $document->id , that is the id of the $document object calling this query. And then saves the $comment object.