ModelRun別のモデル のネストされた属性を受け入れるモデル がありますParameterValue。( ModelRun has_many :parameter_values.) ただし、とParameterValueの 2 つのサブクラスを節約するために、単一テーブルの継承も採用しています。CarrierWaveを使用してファイルを保存します。NumericParameterFileParameterFileParameter
問題は、 をModelRunController保存または更新するときModelRunに、デフォルトで@model_run.saveorが属性@model_run.update_attributesのタイプを識別しないことです。ParameterValue属性を として保存しようとするだけParameterValueです。これはNumericParameter値に対しては機能しますが、 CarrierWave アップローダーがファイルのアップロードを処理するためにマウントされないFileParametersため、例外が発生します。そのため、ActiveRecord はファイルをデータベースにシリアル化しようとすると失敗します。
この問題を処理する最もクリーンな方法は何ですか? 私が思いついた唯一の解決策は、コントローラーとメソッドに@model_run.parameter_valuesコレクションを手動で設定することでした。これは、それぞれがどのタイプであるべきかを判断し、正しいオブジェクトを 1 つずつ作成できるためです。しかし、これは、Rails マジックの多くを再実装しているように思えます。なぜなら、Rails マジックを使用することができなくなったためです。そもそも使用する利点の多くを捨てているようです。Rails Way™ というより良い方法はありますか?createupdateParameterValueModelRun.new(params[:model_run])@model_run.update_attributesaccepts_nested_attributes_for
各モデルの関連部分を以下にコピーします。
model_run.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
file_parameter.rb
class FileParameter < ParameterValue
mount_uploader :parameter_file, ParameterFileUploader
attr_accessible :parameter_file
end
parameter_file_uploader.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