1

Ich habe Modelle Training und Benutzer, die so viele zu viele durch Modell UserWorkout. Und Modell UserWorkout hat Attribut: is_creator, die zeigen, welcher Benutzer der Ersteller war. Aber Workout sollte nur einen Schöpfer haben. Was ist der beste Weg, eine solche Validierung hinzuzufügen?Rails has_many: durch Validierung geschachtelte Datensätze zählen nach bestimmten Parametern

class Workout < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :workout, dependent: :destroy 
    has_many :participants, through: :user_workouts, source: :user 

    def creator 
    participants.where(user_workouts: { is_creator: true }).order('user_workouts.created_at ASC').first 
    end 

end 

class UserWorkout < ActiveRecord::Base 

    belongs_to :user 
    belongs_to :workout 

end 

class User < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :user, dependent: :destroy 
    has_many :workouts, through: :user_workouts 

end 

Antwort

1

Zu allererst hinzufügen gibt es einen Designfehler in Ihre DB-Struktur. Ich denke is_creator sollte nicht in UserWorkout sein. Es ist eine Verantwortung von Workout

Mit anderen Worten Workout von einem Benutzer und einem User erstellt werden können, können viele Workout schaffen, so ist es eine einmehrdeutige Beziehung zwischen User und Workout

ein created_by_id in Workout halten und ein hinzufügen Assoziation darin. Es wird viele Dinge einfacher und einfacher machen.

class Workout < ActiveRecord::Base 

    has_many :user_workouts, inverse_of: :workout, dependent: :destroy 
    has_many :participants, through: :user_workouts, source: :user 

    belongs_to :creator , class_name: "User", foreign_key: "created_by_id" 

end 

und es würde nicht jede Notwendigkeit, die Einzigartigkeit zu überprüfen, da es die einzige Spalte in Workout ist

Jetzt müssen Sie nicht über eine komplexe Abfrage wie jedes Mal, wenn Sie den Schöpfer eines Training finden müssen. Es ist eine einfache belongs_to Assoziation. Alles wird von Schienen besorgt :)

+0

danke für gute Idee) –

2

Je nach DBMS, könnten Sie einen filtered/partial index auf workout_id where is_creator = true

Auf der aktiven Datensatz-Ebene hinzufügen, können Sie einen custom validation

class UserWorkout 
    validate :workout_has_only_one_creator 

    private 

    def workout_has_only_one_creator 
    if self.class.find_by(workout_id: workout_id, is_creator: true) 
     errors.add(:is_creator, 'can only have one creator') 
    end 
    end