Estoy intentando diseñar un sistema de logros en Ruby on Rails y me he encontrado con un problema con mi diseño/código.RoR Achievement System - Asociación polimórfica y problemas de diseño
El intento de utilizar las asociaciones polimórficas:
class Achievement < ActiveRecord::Base
belongs_to :achievable, :polymorphic => true
end
class WeightAchievement < ActiveRecord::Base
has_one :achievement, :as => :achievable
end
Migraciones:
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
Entonces, cuando intento esta prueba siguiente unidad de usar y tirar, se produce un error porque se dice que el logro es nulo.
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
Y mis accesorios: 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
Aunque, no puedo conseguir esto para ejecutar, tal vez en el gran esquema de cosas, es un problema de diseño malo. Lo que intento hacer es tener una sola tabla con todos los logros y su información base (nombre y descripción). Utilizando esa tabla y las asociaciones polimórficas, deseo vincular a otras tablas que contendrán los criterios para completar ese logro, p. la tabla WeightAchievement tendrá el peso requerido y la id del ejercicio. Luego, el progreso de un usuario se almacenará en un modelo UserProgress, donde se vincula con el Logro real (en lugar de WeightAchievement).
La razón por la que necesito los criterios en tablas separadas es porque los criterios variarán enormemente entre diferentes tipos de logros y se agregarán dinámicamente posteriormente, por lo que no estoy creando un modelo separado para cada logro.
¿Esto tiene sentido? ¿Debería simplemente fusionar la tabla de Logros con el tipo específico de logro como Logro de Peso (por lo que la tabla es nombre, descripción, peso_recomendado, ejercicio_id), cuando un usuario consulta los logros, en mi código simplemente busco todos los logros? (Por ejemplo, WeightAchievement, EnduranceAchievement, RepAchievement, etc.)
Gracias - esto es esencialmente lo que estaba buscando pero no pude entender. – MunkiPhD