在管理员动态定义的Rails中存储不同的数据格式

时间:2010-09-28 08:38:35

标签: ruby-on-rails validation activerecord many-to-many jointable

我遇到一个问题,我不能永久地决定我的模型中的哪些列。 一个用例就是这样:

管理员创建新数据集,他希望用户回答。在数据集中,管理员定义了几个不同格式和单位的数据点。

我可以想象这些类与此类似:

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

在我看来,这似乎很有活力,但仍然很容易实现。 我担心的是,如何对创建的每个数据模型进行验证?既然我不能在模型中硬编码验证? 并且为了使它更复杂,如果某些数据点需要额外的验证,例如最小值和最大值,该怎么办?

提前致谢, 纳斯

1 个答案:

答案 0 :(得分:1)

您必须枚举可用验证列表。

然后,您可以创建验证模型和表(如果您希望用户能够重用其验证,则可能是连接表 - 取决于您的用例):

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

然后,在您的data模型中,添加before_save过滤器以调用自定义验证方法:

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

不确定我是否已经完全理解了你的关系,但这样的事情应该会给你一个起点。