Quiero enviar un PR para agregar el método get_like a PluginStore.
get_like recuperará todos los registros para un plugin dado, cuya clave comience con la misma palabra.
Caso de uso
Si un plugin tiene dos o más entidades que desea almacenar, por ejemplo, manzanas y naranjas, almacenará los datos como apple_1, apple_2… y orange_1, orange_2 desde un plugin llamado fruits.
Para obtener todas las naranjas, simplemente se puede llamar a PluginStore.get_like(‘fruits’, ‘orange’), etc.
¿Qué opinan el equipo y los desarrolladores de plugins sobre esto?
No creo que haya necesitado personalmente este patrón. ¿Lo has visto en plugins públicos, o solo en el que estás creando?
Además, no es demasiado largo de escribir:
PluginStoreRow.where("plugin_name = 'fruits' AND key LIKE 'orange%')
Recomendaría agregar una función o clase auxiliar a tu plugin si lo haces con frecuencia. También asegúrate de tener los índices adecuados para estas consultas.
Estaba trabajando en esta función para el plugin custom-wizards y quería obtener todos los magos.
La clave utilizada es una cadena única para cada mago. Este caso se manejaba obteniendo todas las filas del plugin y filtrándolas según el value, lo cual es aceptable para un número pequeño de registros, pero no es ideal para un plugin grande. Parece que plugin_store_rows está destinado a almacenar datos tipo configuración para el plugin.
Personalmente, creo que esto abriría la idea de almacenar datos no tipo configuración en la tabla plugin_store_rows.
En general, recomiendo crear tus propias tablas mediante migraciones si no puedes consultar PluginStoreRow de la manera que deseas. Esto ahora es común en varios plugins y funciona muy bien.
El patrón consiste en utilizar el campo key en la tabla plugin_store_rows para almacenar tanto un espacio de nombres como un identificador único, es decir:
<namespace>_<id>
Este patrón se observa menos en los plugins principales de Discourse en la actualidad, junto con una disminución general en el uso de PluginStore, por ejemplo:
Sin embargo, todavía se utiliza en algunos lugares, incluida la propia base de código principal de Discourse, por ejemplo en el modelo Reviewables.
Yo también utilizo este patrón en varios plugins.
La razón principal por la que se utiliza este patrón es porque la tabla plugin_store_rows es utilizada por múltiples plugins (y algunos servicios principales), por lo que las columnas de identificación, es decir, id y plugin_name, no pueden utilizarse para la identificación interna dentro de cada sistema que utiliza PluginStore. Por lo tanto, se utiliza un sistema basado en cadenas en la columna key.
En cuanto a cambiar la estructura de la base de datos desde dentro de un plugin, @gdpelican tiene una buena publicación sobre esto:
Personalmente, sigo siendo bastante cauteloso al hacer esto, ya que al trabajar en un plugin de terceros no tienes control sobre el espacio de nombres, si tu plugin se elimina o qué cambios potencialmente conflictivos se realizan en el núcleo de Discourse.
Como menciona @gdpelican, debes proporcionar una forma de que el usuario de tu plugin elimine los cambios en la base de datos si desinstala el plugin.
Proporciona un método para que los usuarios limpien los cambios en tu base de datos si ya no quieren tu plugin. Lo hice con una tarea rake.
Siento que esto es demasiado técnico para la mayoría de los usuarios de plugins y representa un riesgo si no son conscientes de este detalle.
Además, no he encontrado una necesidad real de salir de los límites de PluginStore y CustomFields.
Dicho todo esto, personalmente estaría a favor de un nuevo método en PluginStore, como el que se describe a continuación, ya que encuentro útil este patrón.
@david, estaría interesado en conocer tu opinión sobre lo anterior también.
Como ha dicho @eviltrout, ahora estamos utilizando migraciones y tablas dedicadas en varios complementos con gran éxito. La capacidad de aplicar restricciones de base de datos ha ayudado a mejorar el rendimiento (búsquedas en cualquier columna) y la integridad de los datos (mediante índices únicos). Estos dos aspectos han demostrado ser especialmente importantes a la escala de algunos de nuestros clientes alojados; algo que realmente no consideré antes de unirme al equipo.
El primer complemento sustancial en el que trabajé fue chat-integration, e implementé un “activerecord falso” muy complicado, que se apoya en el almacén de complementos. En retrospectiva, las tablas dedicadas habrían sido una opción mucho mejor, y podría considerar migrar el complemento a ese enfoque en el futuro.
Estoy de acuerdo cuando se trata de modificar tablas principales. Agregar o modificar columnas en tablas existentes podría tener consecuencias no deseadas más adelante y permanecerá incluso si el complemento se desinstala. Desaconsejo encarecidamente hacer esto.
Las tablas dedicadas, por otro lado, son de riesgo relativamente bajo. Si el complemento se desinstala, simplemente permanecerán sin efectos secundarios negativos (siempre que no introduzcas restricciones de clave foránea). Dejar datos almacenados no es “peor” que usar el almacén de complementos.
En cuanto a la limpieza, podríamos considerar proporcionar tareas rake que “reviertan” las migraciones de complementos para limpiar. Pero, para ser honesto, no creo que esto se use mucho. Mi suposición es que la gente rara vez desinstala complementos y, cuando lo hacen, prefieren mantener los datos por si acaso quieren volver a instalarlos.
Como autor de ese código, debería aclararlo un poco. Los IDs de prioridad son constantes y no datos relacionales. Recomiendo encarecidamente no usar something_id cuando los IDs no se conocen de antemano. En este caso, cada prioridad se considera un singleton, y pensé que cualquier tabla que creara sería esencialmente un clon de PluginStore.