Question

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 ceci:

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

Je pourrais 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 que je suis inquiet, est de savoir comment faire la validation sur tous les modèles de données qui est créé? Puisque je ne peux pas hardcode la validation dans le modèle? Et pour le rendre encore plus compliqué, si certains ont besoin datapoints supplémentaires, comme des validations comme valeur minimale et maximale?

Merci d'avance, Jonas

Était-ce utile?

La solution

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 table de jointure 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 modèle data, 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top