0

I've been trying for a while to find just the right command to do an upsert, but I have failed miserably.

Here is what I'm trying:

csv.each do |row|
        inner = {}
        if row['PN'] != 'TOTAL'
          time = Time.now
          stamp = time.strftime("%F")
          inner = {
     'PN' => row['PN'],
     'thisWkUse' => row['this WK Usage'], 'thisWkFail' => row['this WK Failure'],     'thisWkFailPercent' => row['this WK Failure%'].gsub('%',''), 
     'prev4WkUse' => row['Previous 4 WK Usage'], 'prev4WkFail' => row['Previous 4 WK     Failure'], 'prev4WkFailPercent' => row['Previous 4 WK Failure%'].gsub('%',''),
     'Platform' => row['Platform'].gsub('%',''),
     'created' => stamp
                   }
          @report = Report.find(PN: inner['PN'], Platform: inner['Platform']).update(inner,[upsert: true ])
          @report.upsert()
        end
     end

Here is the error I'm seeing:

MOPED: someip:someport QUERY        database=reidb collection=reports selector={"_id"=>    {:PN=>"7056733", :Platform=>"CALLISTO_PLUS"}} flags=[] limit=0 skip=0 batch_size=nil fields=nil     runtime: 92.2640ms
Completed 500 Internal Server Error in 447ms

NoMethodError (undefined method `upsert' for nil:NilClass):
 app/controllers/reports_controller.rb:54:in `block in upload'
 app/controllers/reports_controller.rb:42:in `upload'

Here is the model:

class Report
  include Mongoid::Document
  field :_id, type: Object
  field :PN, type: String
  field :thisWkUse, type: Integer
  field :thisWkFail, type: Integer
  field :thisWkFailPercent, type: Float
  field :prev4WkUse, type: Integer
  field :prev4WkFail, type: Integer
  field :prev4WkFailPercent, type: Float
  field :Platform, type: String
  field :created, type: Date
  index({ _id: 1,PN: 1, Platform: 1 }, { unique: true, background: true , drop_dups: true})
end
Simply Seth
  • 3,246
  • 17
  • 51
  • 77
  • You want to use the `where` method for your query (not `find`), see http://mongoid.org/en/mongoid/docs/querying.html – Gary Murakami Sep 06 '14 at 13:23
  • Tried reports = Report.where(:PN => inner['PN'], :Platform => inner['Platform']).new(inner) and reports.upsert and got duplicate records on the second import. – Simply Seth Sep 06 '14 at 23:02
  • Please try: @report = Report.where(PN: inner['PN'], Platform: inner['Platform']).upsert(inner) – Gary Murakami Sep 08 '14 at 17:19

1 Answers1

0

None of the above one liners worked for me, so I did it the ugly way:

inner = {
'PN' => row['PN'],
'thisWkUse' => row['this WK Usage'], 'thisWkFail' => row['this WK Failure'],      'thisWkFailPercent' => row['this WK Failure%'].gsub('%',''), 
'prev4WkUse' => row['Previous 4 WK Usage'], 'prev4WkFail' => row['Previous 4 WK    Failure'], 'prev4WkFailPercent' => row['Previous 4 WK Failure%'].gsub('%',''),
'Platform' => row['Platform'].gsub('%','')
        }
@test = Report.where(:PN => inner['PN'], :Platform => inner['Platform']).count
if @test == 0
  @reports = Report.new(inner)
  @reports.save
elsif @test == 1
  @reports = Report.where(:PN => inner['PN'], :Platform =>       inner['Platform']).update(inner)
else
  limit = @test - 1
  @nuke = Report.where(:PN => inner['PN'], :Platform =>      inner['Platform']).limit(limit).delete
  @reports = Report.where(:PN => inner['PN'], :Platform =>     inner['Platform']).update(inner)
end
Simply Seth
  • 3,246
  • 17
  • 51
  • 77