Updating a record through a hasOneThrough relationship

Viewed 324

I am trying to update or create a new record using the hasOneThrough relationship. A user can have many answers, and one answer can have one conditional answer. I can update the Answers relationship using the User, but I cant figure out how to update ConditionalAnswers through the Answers User relationship?

Error

Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::conditionalAnswers()

user

id

answers

id
user_id

conditional_answers

id
answers_id

User

public function answers(){
    return $this->hasMany(Answers::class);
}

public function conditionalAnswers() {
    return $this->hasManyThrough(ConditionalAnswers::class, Answers::class);
}

Answers

public function user(){
    return $this->belongsTo(User::class);
}

public function conditionalAnswers() {
    return $this->hasOne(ConditionalAnswers::class);
}

ConditionalAnswers

public function user() {
    return $this->hasOneThrough(Answers::class, User::class);
}

public function answers() {
    return $this->belongsTo(Answers::class);
}

Controller

$input = $request->all();
$user = User::find($input['user_id']);

$answers = $user->answers()->updateOrCreate(['user_id' => $user->id, 'key' => 'temp'], $input['answers']); // works fine

$conditionalAnswers = $user->answers()->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); // doesnt work
3 Answers

Try something like this:

$input = $request->all();
$user = User::find($input['user_id']);

$answers = $user->answers()->updateOrCreate(['user_id' => $user->id, 'key' => 'temp'], $input['answers']); // works fine

// $conditionalAnswers = $user->answers()->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); // doesnt work

$conditionalAnswers = collect();
foreach ($user->answers as $answer) {
    $conditionalAnswers = $conditionalAnswers->merge(
        $answer
            ->conditionalAnswers()
            ->updateOrCreate(
                ['answers_id' => $answers->id, 'key' => 'temp_days'],
                ['value' => $input['conditional_answers']]
            ) // should work
    );
}

Since each conditionalAnswer follows one answer, it is sufficient for you to add the conditionalAnswer to the Answer in your controller like this:

$input = $request->all();
$user = User::find($input['user_id']);

$answers = $user->answers()->updateOrCreate(['user_id' => $user->id, 'key' => 'temp'], $input['answers']); 

$conditionalAnswers = $answers->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); 

or you can try:

$conditionalAnswers = new ConditionalAnswers(['key' => 'temp_days'], ['value' => $input['conditional_answers']]);
$answers->conditionalAnswers()->save($conditionalAnswers);

You can read the documentation Inserting & Updating Related Models

in this part of your code u need to specify which answer need to create base or related on.

$conditionalAnswers = $user->answers()->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); // doesnt work

like this

 $conditionalAnswers = $user->answers()->find(id)->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); // replace id in find method

or use created answer object like this.

$answers = $user->answers()->updateOrCreate(['user_id' => $user->id, 'key' => 'temp'], $input['answers']); // works fine

$conditionalAnswers = $answers->conditionalAnswers()->updateOrCreate(['answers_id' => $answers->id, 'key' => 'temp_days'], ['value' => $input['conditional_answers']]); 

i didnt test this code but i think u get the idea.

Related