Rails дублирует записи на has_many через - PullRequest
0 голосов
/ 17 июня 2020

У меня есть веб-сайт, на котором отслеживается, какие песни звучат по радио. Поскольку моя песня была изменена с belongs_to :artist на has_many :artists, я вижу повторяющиеся записи в модели плейлиста, где у песни есть несколько исполнителей. Количество повторяющихся записей равно количеству исполнителей.

Вот настройка:

# models/playlist.rb
class Playlist < ActiveRecord::Base
  belongs_to :song
  has_many :artists, through: :song
  belongs_to :radiostation
  validate :today_unique_playlist_item
end

# models/song.rb
class Song < ActiveRecord::Base
  has_many :playlists
  has_many :radiostations, through: :generalplaylists
  has_many :artists_songs
  has_many :artists, through: :artists_songs
end

# models/artist.rb
class Artist < ActiveRecord::Base
  has_many :artists_songs
  has_many :songs, through: :artists_songs
  has_many :playlists, through: :songs
  has_many :radiostations, through: :playlists
end

# models/artist_songs.rb
class ArtistsSong < ApplicationRecord
  belongs_to :artist
  belongs_to :song
end

Я добавил настраиваемую проверку в список воспроизведения, чтобы проверить уникальность. Тесты RSpe c работают отлично, но все еще есть повторяющиеся записи. Так что я предполагаю, что это проблема с базой данных. Я использую PostgreSQL.

# custom validation
def today_unique_playlist_item
  exisiting_record = Generalplaylist.joins(:song, :radiostation).where('songs.id = ? AND time = ? AND radiostations.id = ? AND generalplaylists.created_at > ?', song_id, time, radiostation_id, 1.day.ago).present?
  errors.add(:base, 'none unique playlist') if exisiting_record
end

Примечание: я получаю только последний день, так как текущее время трансляции (атрибут playlist.time) не имеет даты. Текущий формат: 22:00

Я подумываю добавить индекс модели плейлиста в схему, но не уверен, что это решит проблему и что туда поместить.

Любая помощь приветствуется.

1 Ответ

0 голосов
/ 18 июня 2020

Проблема, с которой вы столкнулись, вероятно, заключается в том, что пользовательская проверка запускает выбор в базе данных перед вставкой записи.

Это означает, что если две одновременные проверки выполняются, они обе не увидят уникальной записи и продолжат к следующей строке кода, которая, вероятно, вставляет запись, вызывая дублирование вставок.

Я бы рекомендовал использовать Active Record Import и вместо этой проверки установите уникальное ограничение для Playlist и сделайте апсерт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...