RoR Achievement System - Polymorphic Association & Design Issues
Ich versuche, ein Leistungssystem in Ruby on Rails zu entwerfen, und bin mit meinem Design / Code auf einen Haken gestoßen.
Versuch polymorphe Assoziationen zu verwenden:
class Achievement < ActiveRecord::Base
belongs_to :achievable, :polymorphic => true
end
class WeightAchievement < ActiveRecord::Base
has_one :achievement, :as => :achievable
end
Migrationen:
class CreateAchievements < ActiveRecord::Migration
... #code
create_table :achievements do |t|
t.string :name
t.text :description
t.references :achievable, :polymorphic => true
t.timestamps
end
create_table :weight_achievements do |t|
t.integer :weight_required
t.references :exercises, :null => false
t.timestamps
end
... #code
end
Wenn ich dann diesen folgenden Einweg-Unit-Test versuche, schlägt er fehl, weil er besagt, dass die Errungenschaft null ist.
test "parent achievement exists" do
weightAchievement = WeightAchievement.find(1)
achievement = weightAchievement.achievement
assert_not_nil achievement
assert_equal 500, weightAchievement.weight_required
assert_equal achievement.name, "Brick House Baby!"
assert_equal achievement.description, "Squat 500 lbs"
end
Und meine Fixtures: achievements.yml ...
BrickHouse:
id: 1
name: Brick House
description: Squat 500 lbs
achievable: BrickHouseCriteria (WeightAchievement)
weight_achievements.ym ...
BrickHouseCriteria:
id: 1
weight_required: 500
exercises_id: 1
Auch ich kann das nicht zum Laufen bringen, vielleicht im großen Stil, es ist ein schlechtes Designproblem. Was ich versuche zu tun, ist eine einzige Tabelle mit allen Erfolgen und ihren Basisinformationen (Name und Beschreibung). Unter Verwendung dieser Tabelle und der polymorphen Assoziationen möchte ich eine Verknüpfung zu anderen Tabellen herstellen, die die Kriterien für den Abschluss dieser Leistung enthalten, z. Die WeightAchievement-Tabelle enthält das erforderliche Gewicht und die Übungs-ID. Anschließend wird der Fortschritt eines Benutzers in einem UserProgress-Modell gespeichert, in dem er mit dem tatsächlichen Erfolg verknüpft ist (im Gegensatz zu WeightAchievement).
Der Grund, warum ich die Kriterien in separaten Tabellen benötige, ist, dass die Kriterien je nach Leistungstyp stark variieren und anschließend dynamisch hinzugefügt werden. Deshalb erstelle ich kein separates Modell für jede Leistung.
Macht das überhaupt Sinn? Soll ich die Achievement-Tabelle einfach mit dem bestimmten Leistungstyp wie WeightAchievement zusammenführen (die Tabelle lautet also name, description, weight_required, exercise_id), und wenn ein Benutzer die Leistungen abfragt, suche ich in meinem Code einfach alle Leistungen? (z. B. WeightAchievement, EnduranceAchievement, RepAchievement usw.)