2009-10-17 4 views
7

Est-ce que quelqu'un connaît une gemme ou une bonne implémentation permettant à l'utilisateur d'ajouter des champs à un modèle?Champs de modèle dynamique spécifiés par l'utilisateur dans Rails

Ex.

L'utilisateur souhaite ajouter un champ "notes internes" au modèle de contact. Dans l'interface ils suffit de sélectionner « Nouveau champ »> « Type: Texte »

Merci

Répondre

6

Je suis désolé, je ne connais pas de plug-in pour le faire. Mais j'ai une suggestion de mise en œuvre.

L'idée est d'ajouter un modèle "DynamicField" qui serait une relation has_many avec le modèle Contact. Lorsque vous avez une méthode manquante dans le modèle Contact, vous vérifiez s'il existe un champ dynamique pour le récupérer si c'est le cas.

class DynamicField < ActiveRecord::Base 
    belongs_to :contact 
end 


class Contact < ActiveRecord::Base 
    has_many :dynamic_fields 

    def method_missing(sym, *args, &block) 
     begin 
      super 
     rescue 
      field = dynamic_fields.find_by_name(sym) 
     end 
     raise ActiveRecord::NoMethodError if field.nil? 
     field.value 
    end 
end 

Vous aurez besoin d'ajouter un regex si vous souhaitez ajouter des attributs virtuels avec l'attribut = méthode (détection de la présence d'un « = » et de faire une mise à jour au lieu de seulement obtenir la valeur). Mais vous avez déjà ici l'idée. Lorsque la méthode n'existe pas, nous vérifions les champs dynamiques s'il y en a un avec le même nom. S'il n'y a pas (field.nil?), Nous levons une NoMethodError. Sinon, nous le retournons.

Ainsi, vous pouvez obtenir une liste de tous vos champs avec les éléments suivants:

Contact.find(:first).dynamic_fields 

et récupérer un spécifique avec les éléments suivants:

Contact.find(:first).my_dynamic_field 
2

Voici une autre façon de le faire.

Avertissement: Cette méthode est déconseillée en raison de son potentiel d'abus. En fait, il ne devrait être accessible qu'aux administrateurs de votre site.

class MyModel < ActiveRecord::Base 
    ... 
    def self.add_column(name, type, args= {}) 
    ActiveRecord::Migration.add_column table_name, name, type, args 
    end 
end 
Questions connexes