我有一个模型,ModelRun
接受另一个模型的嵌套属性,ParameterValue
。( ModelRun has_many :parameter_values
.) 但是,ParameterValue
也使用单表继承来保存两个子类:NumericParameter
和FileParameter
. FileParameter
使用CarrierWave存储文件。
问题在于,在ModelRunController
保存或更新 aModelRun
时,默认情况下@model_run.save
或@model_run.update_attributes
不识别ParameterValue
属性的类型 - 它只是尝试将它们存储为ParameterValue
. 这适用于NumericParameter
值,但它引发了一个例外,FileParameters
因为CarrierWave 上传器没有被挂载来处理文件上传,因此 ActiveRecord 在尝试将文件序列化到数据库时失败。
处理这个问题的最干净的方法是什么?我想到的唯一解决方案是在控制器和方法中手动填充@model_run.parameter_values
集合,因为我可以分辨每个应该是哪种类型并一个一个地创建正确的对象。然而,这似乎重新实现了很多 Rails 魔法,因为我不能只使用或不再使用 - 似乎它首先放弃了使用的大部分优势。有没有更好的方法,Rails Way™?create
update
ParameterValue
ModelRun.new(params[:model_run])
@model_run.update_attributes
accepts_nested_attributes_for
每个模型的相关部分复制如下。
模型运行.rb
class ModelRun < ActiveRecord::Base
has_many :parameter_values, dependent: :destroy
accepts_nested_attributes_for :parameter_values, allow_destroy: true
attr_accessible :name,
:description,
:geometry_description,
:run_date,
:run_date_as_string,
:parameter_values_attributes
end
参数值.rb
class ParameterValue < ActiveRecord::Base
belongs_to :model_run
attr_accessible :type,
:parameter_id,
:description,
:numeric_value,
:model_run_id,
:parameter_file
end
数字参数.rb
class NumericParameter < ParameterValue
attr_accessible :numeric_value
end
文件参数.rb
class FileParameter < ParameterValue
mount_uploader :parameter_file, ParameterFileUploader
attr_accessible :parameter_file
end
参数文件上传器.rb
class ParameterFileUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
"#{Rails.root}/uploads/#{model.class.to_s.underscore}/#{model.id}"
end
def cache_dir
"#{Rails.root}/tmp/uploads/cache/#{model.id}"
end
end