Entonces, pensé que tenía esto funcionando anoche, podría haberlo jurado. Ahora no funciona, y creo que es hora de pedir ayuda.ruby on rails campos de atributos dinámicos de DB utilizando los problemas de method_missing
Im campos dinámicos definen en la base de datos, estilo semi EAV, y le acaba de afirmar en este momento no me importa escuchar sus opiniones sobre si EAV es una buena idea o no :)
De todas formas estoy haciendo un poco de forma diferente a como lo hice en el pasado, básicamente cuando se agrega un atributo (o campo), creo una columna de agregar a una migración de la tabla de atributos en particular y la ejecuto (o la elimino) - ANYWAYS, porque hay una capa de categoría sentado en el medio, que es la relación directa donde se definen todos los atributos, no puedo usar el nombre del atributo real como nombre de columna, ya que los atributos son específicos de la categoría.
Por lo tanto, si ayuda a visualizar
Entity
belongs_to :category
Category
has_many :entities
EntityAttribute
belongs_to :category
EntityAttributeValue
belongs_to :entity_attribute
belongs_to :entity
y mesa de EAV se extiende horizontalmente a medida que se crean nuevos atributos, con columnas etiquetadas attribute_2 attribute_1, que contienen los valores de esa entidad en particular.
De todas formas - Estoy tratando de hacer que los métodos dinámicos en el modelo de entidad, por lo que puedo llamar @ entity.actual_attribute_name, en lugar de @ entity.entity_attribute_value.field_5
Este es el código que pensé que estaba trabajando - -
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
Entonces hoy como volví al código, me di cuenta, aunque podía establecer el atributo en la consola de rieles, y sería devolver el campo correcto, cuando guarda el registro, la EntityAttributeValue no estaba siendo actualizado (representado como self.project_category_field_value, arriba.)
Así que después de analizarlo aún más, parecía que solo tenía que agregar una devolución de llamada before_update o before_save para guardar el atributo manualmente, y es allí donde noté, en la devolución de llamada, que volvería a ejecutar la devolución de llamada method_missing, como si el objeto fuera al estar duplicado (y el nuevo objeto era una copia del objeto original), o algo así, no estoy del todo seguro. Pero en algún momento durante el proceso de guardar o antes, mi atributo desaparece en el olvido.
Bueno, supongo que a mitad de camino respondí mi propia pregunta después de tipearla, necesito establecer una variable de instancia y verificar si existe al principio de mi método method_missing (¿no?) Tal vez eso no es lo que sucediendo, no lo sé, pero también estoy preguntando si hay una forma mejor de hacer lo que estoy tratando de hacer. Y si utilizar method_missing es una mala idea, explique por qué, al pasar por mensajes sobre el método faltante oí que algunas personas lo criticaban pero ninguna de esas personas se molestó en ofrecer una explicación razonable de por qué el método faltante era una mala solución .
Gracias de antemano.
gracias por la respuesta, no pude hacerlo funcionar solo por el código anterior pero utilicé parte de él en la refactorización, así que acepté como respuesta – thrice801