2010-12-13 6 views
2

Je suis un peu nouveau pour Ruby et Rails et je suis en train de comprendre comment modéliser la relation suivante en utilisant langage dynamique de Ruby ....Comment modéliser une relation de base de données de questionnaire en utilisant les propriétés dynamiques

Le domaine est essentiellement un questionnaire, donc j'ai des utilisateurs, des questions et des réponses.

Un utilisateur a un ID et un nom. Une réponse a un ID utilisateur et un ID de question et une propriété valeur qui est la réponse de l'utilisateur à cette question particulière.

Chaque question a un 'Code' unique, par exemple, une question pourrait être "Quelle est votre couleur préférée?", Et le code serait "fav_color".

Si j'ai une instance User, je veux être en mesure de faire: user.fav_color pour obtenir/définir cette réponse.

Je me dis que je pourrais essayer de method_missing utilisateur, puis faire un appel finder comme dans cet exemple: http://rpheath.com/posts/241-how-to-use-method-missing

Ou puis-je ajouter dynamiquement des propriétés à une classe à l'exécution comme ici:

Ruby - dynamically add property to class (at runtime)

Mais j'ai besoin de lire/écrire dans la base de données .... simplement stocker ces propriétés dynamiques dans une variable d'instance n'est pas bon pour moi.

Toute aide serait appréciée ... ou des conseils sur une meilleure façon d'aborder ce problème :)

Répondre

0

Je suis venu avec la réponse suivante à ma question ... grâce à l'affiche précédente (iain) qui m'a mis dans la bonne direction.

class User < ActiveRecord::Base 
    has_many :answers 

    Question.all.each do |q| 
    define_method q.code do 
     a = answers.find_by_question_id(q.id) 
     a && a.value || q.default_value 
    end 
    define_method "#{q.code}=" do |value| 
     a = answers.find_by_question_id(q.id) || answers.new({:question_id => q.id}) 
     a.value = value 
     a.save 
    end 
    end 

La seule question que j'ai avec cette solution est que si je montre un utilisateur avec toutes les réponses, il y a une requête de base de données distincte pour chaque question. J'aurais pensé que la collection: réponses ne serait chargée qu'une seule fois ...

1
code = "fav_color" 
User.class_eval do 
    define_method code do 
    read_attribute code 
    end 
    define_method "#{code}=" do |value| 
    write_attribute code, value 
    end 
end 
+0

Merci de m'avoir indiqué la direction d'écriture. Cependant, comme vous pouvez le constater d'après ma réponse, je dois «transposer» les attributs de l'utilisateur sur la table des réponses. Désolé si je n'ai pas rendu cela plus clair dans ma question. – Darragh

Questions connexes