Как смоделировать отношение базы данных анкеты с использованием динамических свойств - PullRequest
2 голосов
/ 14 декабря 2010

Я немного новичок в Ruby и Rails, и я пытаюсь выяснить, как смоделировать следующее отношение, используя возможности динамического языка Ruby ....

Домен - это, по сути, вопросник, поэтому яесть пользователи, вопросы и ответы.

У пользователя есть идентификатор и имя.Ответ имеет идентификатор пользователя и вопросительный идентификатор, а также свойство value, которое является ответом пользователя на этот конкретный вопрос.

Каждый вопрос имеет уникальный «Код», поэтому, например, вопрос может звучать так: «Каков вашлюбимый цвет? ", и код будет" fav_color ".

Если у меня есть экземпляр User, я хочу иметь возможность: user.fav_color, чтобы получить / установить этот ответ.

Я полагаю, что я мог бы попробовать и пользователь method_missing, а затем сделать вызов Finder, как в этом примере: http://rpheath.com/posts/241-how-to-use-method-missing

Или я могу динамически добавлять свойства в класс во время выполнения, как здесь:

Ruby - динамически добавлять свойство в класс (во время выполнения)

Но мне нужно читать / писать в базу данных .... простое сохранение этих динамических свойств в переменной экземпляра не годится дляя.

Любая помощь будет высоко ценится ... или совет о лучшем способе решения этой проблемы:)

Ответы [ 2 ]

1 голос
/ 14 декабря 2010
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 голосов
/ 16 декабря 2010

Я получил следующий ответ на мой вопрос ... благодаря предыдущему постеру (iain), который поставил меня в правильном направлении.

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

Единственная проблема, с которой я столкнулсяРешение состоит в том, что если я показываю пользователю все ответы, то для каждого вопроса есть отдельный запрос к базе данных.Я бы подумал: коллекция ответов будет загружена только один раз ...

...