Отношения Laravel Morph - detatch / attatch
У меня есть эти реляционные модели:
Моя главная цель - создать реакции на систему, чтобы они могли быть связаны с N идентичностями (например: статья, фото, новости, ...)
Схема реакций:
public function up()
{
Schema::create('reactions', function (Blueprint $table){
$table->increments('id');
$table->string('title', 50)->unique()->index();
$table->string('show_text', 20);
$table->smallInteger('ordering')->nullable()->default(null);
});
}
Схема реагирующих веществ:
Schema::create('reactionables', function (Blueprint $table) {
$table->increments('id');
$table->integer('reactor_id')->unsigned();
$table->integer('reaction_id')->unsigned();
$table->foreign("reactor_id")->references("id")->on("users");
$table->foreign("reaction_id")->references("id")->on("reactions");
$table->morphs('reactionable');
$table->timestamp('created_at')->nullable();
});
Черта hasReactions (для применения к реакционным объектам, таким как Post, Images и т. д.):
/**
* Get related reactions
*
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
public function reactions()
{
return $this->morphToMany(Reaction::class, 'reactionable')
->withPivot(['reactionable_id', 'reactionable_type']);
}
Черта isReactor (применяется к пользователям):
/**
* React to given instance
*
* @param Reactionable $reactionable
* @param ReactionType $applied_reaction
*
* @return bool
*/
public function react(Reactionable $reactionable, ReactionType $applied_reaction)
{
$reactionable->reactions()
->detach(
$reactionable->reactions()->where('reactor_id', $this->getKey())->get(['reactions.id'])->toArray()
);
return $this->storeReaction($reactionable, $applied_reaction);
}
/**
* Store reaction
*
* @param Reactionable $reactionable
* @param ReactionType $applied_reaction
*
* @return bool
*/
private function storeReaction(Reactionable $reactionable, ReactionType $applied_reaction)
{
try {
$reactionable->reactions()->attach(
$applied_reaction->getKey(), [
'reactor_id' => $this->getKey(),
'created_at' => Carbon::now()
]
);
return true;
} catch (\Throwable $exception) {
return false;
}
}
Основная проблема здесь в том, что иногда (случайно, я не мог понять, как это происходит), реакция для некоторого случайного пользователя удаляет все другие реакции.
Я даже не знаю, является ли это лучшим решением для этой проблемы - я не хочу применять строгие отношения между реакциями ~ сообщениями, применяющими обратные отношения, поэтому я и подаю заявку на это.