1

Je suis face à un problème où je ne peux pas décider de façon permanente les colonnes un de mes modèles auront. Un cas d'utilisation sera la suivante:Stockage des différents formats de données dans Rails définies dynamiquement par admin

Un administrateur crée un nouvel ensemble de données, il souhaite que les utilisateurs de répondre. Dans l'ensemble de données, l'administrateur définit plusieurs points de données de format et d'unités différents.

je pouvais imaginer les classes pour ressembler à ceci:

class Dataset < ActiveRecord::Base 
has_many :measurements 
has_many :profiles, :through => :measurements 
has_many :datapoints, :through => :dataset_datapoint 
end 

# Join table 
class Dataset_datapoint < ActiveRecord::Base 
belongs_to :dataset 
belongs_to :datapoint 
end 

class Datapoint < ActiveRecord::Base 
has_many :dataset, :through => :dataset_datapoint 
has_many :data 
# create_table "datapoints" do |t| 
# t.string :name 
# t.string :format # e.g. string, decimal etc. 
# t.string :unit # e.g. CM, pounds etc. 
end 

class Data < ActiveRecord::Base 
belongs_to :datapoint 
# create_table "data" do |t| 
# t.integer :datapoint_id 
# t.string :value # This column could be anything from string to decimal 
end 

Dans ma tête, cela semble assez dynamique, mais encore assez facile à mettre en œuvre. Ce qui m'inquiète, c'est comment faire la validation sur chaque modèle de données créé? Puisque je ne peux pas coder en dur la validation dans le modèle? Et pour le rendre encore plus compliqué, que se passe-t-il si certains points de données nécessitent des validations supplémentaires, telles que la valeur minimale et maximale?

Merci à l'avance, Jonas

Répondre

1

Vous devez énumérer la liste des validations disponibles.

Ensuite, vous pouvez créer un modèle de validation et de la table (et peut-être une jointure table si vous souhaitez que les utilisateurs soient en mesure de réutiliser leurs validations - dépend de vos cas d'utilisation):

class Validation < ActiveRecord::Base 
    belongs_to :dataset 
    # create_table 'validations' do |t| 
    # t.references :dataset 
    # t.string :type 
    # ... and columns for each restriction you could apply, ie: 
    # t.integer :max_value  
    # t.integer :min_value 
    # t.string :regexp 
    # ...etc... 
end 

Ensuite, dans votre data modèle, ajouter un filtre before_save pour appeler votre méthode de validation personnalisée:

class Data < ActiveRecord::Base 
    belongs_to :datapoint 
    has_many :validations, :through => :datapoint 
    before_save :custom_validation 

private 
    def custom_validation 
    validations.each do |validation| 
     if validation.type == 'integer_range' 
     unless value < validation.max_value and value > validation.min_value 
      # return false, or add an error on the value attribute, or whatever 
     end 
     # More validations here - use a case statement probably 
    end 
    end 
end 

Je ne sais pas si j'ai vos relations exactement compris, mais quelque chose comme cela devrait vous donner un point de départ.

+0

Merci accouplent, il sonne comme une solution tout à fait raisonnable. J'ai eu en fait un peu les mêmes pensées à l'esprit, mais pensé d'une manière beaucoup plus complexe. –

Questions connexes