Итак, я думал, что это работало прошлой ночью, могу поклясться. Теперь это не работает, и я полагаю, что пришло время обратиться за помощью.
Я определяю динамические поля в базе данных в полу-стиле EAV, и давайте просто заявим прямо сейчас, что мне все равно, что вы думаете о том, является ли EAV хорошей идеей или нет :)
В любом случае, я делаю это немного иначе, чем Я делал это в прошлом, в основном, когда атрибут (или поле) добавляется, я создаю столбец добавления для миграции таблицы определенных атрибутов и запускаю его (или удаляю его) - В ЛЮБОМ СЛУЧАЕ, потому что есть слой категории, находящийся в середина, которая представляет собой прямую связь, в которой определены все атрибуты, я не могу использовать фактическое имя атрибута в качестве имени столбца, поскольку атрибуты зависят от категории.
Итак, если это поможет вам визуализировать
Entity
belongs_to :category
Category
has_many :entities
EntityAttribute
belongs_to :category
EntityAttributeValue
belongs_to :entity_attribute
belongs_to :entity
И таблица EAV растягивается по горизонтали по мере создания новых атрибутов со столбцами, помеченными атрибут_1 атрибут_2, которые содержат значения для этого конкретного объекта.
В любом случае -- я пытаюсь сделать методы динамическими в модели объекта, поэтому я могу вызывать @entity.actual_attribute_name, а не @entity.entity_attribute_value.field_5
Вот код, который, как мне казалось, работал --
def method_missing(method, *args)
return if self.project_category.blank?
puts "Sorry, I don't have #{method}, let me try to find a dynamic one."
puts "let me try to find a dynamic one"
keys = self.project_category.dynamic_fields.collect {|o| o.name.to_sym }
if keys.include?(method)
field = self.project_category.dynamic_fields.select { |field| field.name.to_sym == method.to_sym && field.project_category.id == self.project_category.id }.first
fields = self.project_category.dynamic_field_values.select {|field| field.name.to_sym == method }
self.project_category_field_value.send("field_#{field.id}".to_sym, *args)
end
end
Затем сегодня, когда я вернулся к коду, я понял, что хотя я могу установить атрибут в консоли rails, и он вернет правильное поле, когда я сохранил запись, EntityAttributeValue не обновлялся (представлен как self.project_category_field_value, выше.)
Итак, после дальнейшего изучения оказалось, что мне просто нужно было добавить обратный вызов before_update или before_save, чтобы вручную сохранить атрибут, и именно здесь я заметил, что в обратном вызове он повторно запускает обратный вызов method_missing, как если бы объект дублировался (и новый объект был копией исходного объекта) или что-то в этом роде, я не совсем уверен. Но в какой-то момент во время процесса сохранения или до этого мой атрибут исчезает в небытие.
Итак, я думаю, я наполовину ответил на свой вопрос после того, как напечатал его, мне нужно установить переменную экземпляра и проверить, существует ли она в начале моего метода method_missing (правильно?) Может быть, это не то, что происходит Я не знаю, но я также спрашиваю, есть ли лучший способ сделать то, что я пытаюсь сделать.
И если использование method_missing — плохая идея, пожалуйста, объясните, почему, поскольку, просматривая сообщения об отсутствующих методах, я слышал, как некоторые люди хлопали по этому поводу, но никто из этих людей не удосужился предложить разумное объяснение того, почему отсутствие метода было плохим решением.
Заранее спасибо.