Rails と Ruby は初めてで、正しいことをしようとしています。
これが私のモデルです。すべてうまくいきますが、いわば「正しい」方法で物事を進めたいと思っています。CSV を取得し、新しいレコードを作成するか、既存のレコードを更新しようとするインポート プロセスがあります。
したがって、プロセスは 1.) csv 行を解析する 2.) レコードを検索または作成する 3.) レコードを保存する
これは完全に機能していますが、コードは改善できるようです。ParcelType が関与していない場合は、メーカーから小包を作成/取得しているため、その外部キーが事前に入力されているため、問題ありません。しかし、ParcelType はそうではありません。とにかく、検索で両方を使用しているので、タイプとメーカーの両方を事前に入力するにはどうすればよいですか?
CSV 行には、行ごとに複数のメーカーを含めることができます (結果は 2 つのほぼ同一の行になり、diff mfr_id だけです)、それが .each の目的です
manufacturer_id.split(";").each do |mfr_string|
mfr = Manufacturer.find_by_name(mfr_string)
# If it's a mfr we don't care about, don't put it in the db
next if mfr.nil?
# Unique parcel is defined by it's manufacturer, it's type, it's model number, and it's reference_number
parcel = mfr.parcels.of_type('FR').find_or_initialize_by_model_number_and_reference_number(attributes[:model_number], attributes[:reference_number])
parcel.assign_attributes(attributes)
# this line in particular is a bummer. if it finds a parcel and I'm updating, this line is superfulous, only necessary when it's a new parcel
parcel.parcel_type = ParcelType.find_by_code('FR')
parcel.save!
end
class Parcel < ActiveRecord::Base
belongs_to :parcel_type
belongs_to :manufacturer
def self.of_type(type)
joins(:parcel_type).where(:parcel_types => {:code => type.upcase}).readonly(false) unless type.nil?
end
end
class Manufacturer < ActiveRecord::Base
has_many :parcels
end
class ParcelType < ActiveRecord::Base
has_many :parcels
end