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

听起来像new_record?方法就是你要找的。

new_record?() 公开的

如果此对象尚未保存,则返回 true ——也就是说,该对象的记录尚不存在;否则,返回 false。

只有当包裹对象确实是新记录时,才会执行以下操作:

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

'find_or_create' 呢?我很早就想使用它,请检查这些链接。

于 2012-12-10T20:04:09.673 回答