ruby ​​on rails динамические поля атрибутов из БД с использованием method_missing Issues

Итак, я думал, что это работало прошлой ночью, могу поклясться. Теперь это не работает, и я полагаю, что пришло время обратиться за помощью.

Я определяю динамические поля в базе данных в полу-стиле 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 — плохая идея, пожалуйста, объясните, почему, поскольку, просматривая сообщения об отсутствующих методах, я слышал, как некоторые люди хлопали по этому поводу, но никто из этих людей не удосужился предложить разумное объяснение того, почему отсутствие метода было плохим решением.

Заранее спасибо.

6
задан thrice801 5 April 2012 в 01:13
поделиться