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