0

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
4

2 に答える 2

0

「find_or_create」はどうですか? ずっと使いたかったので、リンク先をチェック。

于 2012-12-10T20:04:09.673 に答える
0

new_record?のようですね。メソッドはあなたが探しているものです。

new_record?() パブリック

このオブジェクトがまだ保存されていない場合、つまりオブジェクトのレコードがまだ存在しない場合は true を返します。それ以外の場合は false を返します。

以下は、区画オブジェクトが実際に新しいレコードである場合にのみ実行されます。

parcel.parcel_type = ParcelType.find_by_code('FR') if parcel.new_record?
于 2012-12-10T18:07:27.287 に答える