0

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
4

1 に答える 1