使用延迟作业时出错“无方法”

时间:2013-08-10 09:34:08

标签: ruby-on-rails xml-parsing delayed-job

我正在尝试将90k行xml导入我的ruby应用程序。 herokus超时限制为30秒,所以我试图使用延迟工作。

导入课在当地大约48个河马中运作良好。当我添加行

  handle_asynchronously :save_races

我收到错误“未定义的方法save_races' for class Xmltube”“

我在DJ身上做错了什么?如何才能让它发挥作用?

以下全类代码

require "rexml/document"
class Xmltube  
  def self.convert_save(xml_data)
    doc = REXML::Document.new xml_data.read                        
    doc.elements.each("Meeting") do |meeting_element| 
      meeting = save_meeting(meeting_element)
      save_races(meeting_element, meeting)
      Rails.logger.info "all done"      
    end
  end

  def self.save_races(meeting_element,  meeting)

    meeting_element.elements.each("Races/Race") do |race_element|      
      race = save_race(race_element, meeting) 
      save_race_entrants(race_element, race)                        
    end
  end

  def self.save_race_entrants(race_element, race)
    race_element.elements.each("RaceEntries/RaceEntry") do |entry_element|
      horse = save_horse(entry_element)
      jockey = save_jockey(entry_element)
      start = save_start(entry_element, horse, jockey, race) 
      save_sumaries(entry_element, start)
    end   
  end 

  def self.save_track(meeting_element)
    # there is only one track, but still, each? wtf.
    t = {}
    meeting_element.elements.each("Track") do |track|        
      t = {
        :name       =>  track.attributes["VenueName"],
        :track_code =>  track.attributes["VenueCode"],          
        :condition  =>  track.elements['TrackRating'].text,
        :club_id    =>  save_club(meeting_element.elements["Club"]).id
      }         
    end    

    track = Track.where(:track_code =>  t[:track_code]  ).first  
    if track
      Track.update(track.id, t)    
    else      
      Track.create(t)        
    end    
  end

  def self.save_meeting meeting_element
    t = {
      :meet_code  =>  meeting_element.attributes['MeetCode'],          
      :stage      =>  meeting_element.elements["MeetingStage"].text,          
      :phase      =>  meeting_element.elements["MeetingPhase"].text,          
      :nominations_close_at =>  meeting_element.elements["NominationsClose"].text, 
      :acceptance_close_at =>   meeting_element.elements["AcceptanceClose"].text,           
      :riders_close_at      =>  meeting_element.elements["RidersClose"].text,           
      :weights_published_at =>  meeting_element.elements["WeightsPublishing"].text,          
      :club_id =>  save_club(meeting_element.elements["Club"]).id ,
      :track_id => save_track(meeting_element).id,
      :tab_status =>  meeting_element.elements["TabStatus"].text, 
      :state =>  meeting_element.elements["StateDesc"].text, 
      :day_night =>  meeting_element.elements["DayNight"].text, 
      :number_of_races =>  meeting_element.elements["NumOfRaces"].text, 
      :meet_date =>  meeting_element.elements["MeetDate"].text, 
    }         


    meeting = Meeting.where(:meet_code =>  t[:meet_code]  ).first  
    if meeting
      Meeting.update(meeting.id, t)    
    else      
      Meeting.create(t)        
    end    
  end

  ############################################################

  def self.save_sumaries entry_element, start  
    entry_element.elements.each('Form/ResultsSummaries/ResultsSummary') do | element |
      s = {
        :name             =>  element.attributes['Name'],
        :start_id         =>  start.id,
        :starts           =>  element.attributes['Starts'],
        :wins             =>  element.attributes['Wins'],
        :seconds          =>  element.attributes['Seconds'],
        :thirds           =>  element.attributes['Thirds'],
        :prize_money      =>  element.attributes['PrizeMoney'],        
      }

      sum = Summary.where(:name =>  s[:name] ).where(:start_id => s[:start_id]).first  
      if sum
        Summary.update(sum.id, s)    
      else      
        Summary.create(s)        
      end 
    end     
  end

  def self.save_start entry_element, horse, jockey, race
    s = {
      :horse_id    =>  horse.id,
      :jockey_id   =>  jockey.id,
      :race_id     =>  race.id,
      :silk        =>  entry_element.elements["JockeySilksImage"].attributes["FileName_NoExt"], 
      :start_code  =>  entry_element.attributes['RaceEntryCode'],
      :handicap_weight =>  entry_element.elements['HandicapWeight'].text, 
    }
   # Rails.logger.info entry_element['HandicapWeight'].text
    start = Start.where(:start_code =>  s[:start_code]  ).first  
    if start
      Start.update(start.id, s)    
    else      
      Start.create(s)        
    end  
  end

  def self.save_jockey entry_element
    j={
      :name         =>  entry_element.elements['JockeyRaceEntry/Name'].text,
      :jockey_code  =>  entry_element.elements['JockeyRaceEntry'].attributes["JockeyCode"],
    }
    jockey = Jockey.where(:jockey_code =>  j[:jockey_code]  ).first  
    if jockey
      Jockey.update(jockey.id, j)    
    else      
      Jockey.create(j)        
    end      
  end

  def self.save_horse entry_element
    trainer = save_trainer entry_element
    h= {
      :name       =>  entry_element.elements['Horse'].attributes["HorseName"],          
      :color      =>  entry_element.elements['Horse'].attributes["Colour"],          
      :dob        =>  entry_element.elements['Horse'].attributes["FoalDate"],           
      :sex        =>  entry_element.elements['Horse'].attributes["Sex"],           
      :trainer_id =>  trainer.id,
      :horse_code =>  entry_element.elements['Horse'].attributes["HorseCode"],                 
    }
    horse = Horse.where(:horse_code =>  h[:horse_code]  ).first  
    if horse
      Horse.update(horse.id, h)    
    else      
      Horse.create(h)        
    end        
  end

  def self.save_trainer entry_element
    t= {
        :name         =>  entry_element.elements['Trainer/Name'].text,
        :trainer_code =>  entry_element.elements['Trainer'].attributes["TrainerCode"]  
      }
    trainer = Trainer.where(:trainer_code =>  t[:trainer_code]  ).first  
    if trainer
      Trainer.update(trainer.id, t)    
    else      
      Trainer.create(t)        
    end    
  end  

  def self.save_club element
    t = {}      
      t = {
        :club_code  =>  element.attributes['ClubCode'],          
        :title      =>  element.attributes["Title"],          
      }             
    club = Club.where(:club_code =>  t[:club_code]  ).first  
    if club
      Club.update(club.id, t)    
    else      
      Club.create(t)        
    end    
  end

  def self.save_race element, meeting
    r = {
        :name       =>  element.elements['NameRaceFull'].text,
        :occur      =>  element.elements['RaceStartTime'].attributes["TimeAtVenue"],          
        :distance   =>  element.elements['RaceDistance'].text,
        :race_type  =>  element.elements['RaceType'].text,
        :track_id   =>  meeting.track_id,
        :race_code  =>  element.attributes["RaceCode"],
        :meeting_id => meeting.id       
      }        
    race = Race.where(:race_code =>  r[:race_code]  ).first  
    if race
      Race.update(race.id, r)    
    else      
      Race.create(r)        
    end  
  end

  handle_asynchronously :save_races
end 

2 个答案:

答案 0 :(得分:1)

由于您的save_races是一种类方法,因此您应该在handle_asynchronously的单例类上调用Xmltube

class << self
  handle_asynchronously :save_races
end

答案 1 :(得分:0)

这就像我期望的那样工作

class Foo
  def self.bar(s)
    Rails.logger.info "From Foo.bar('#{s}')"
  end
end

# then ...
Foo.delay.bar('hello')

我用ruby 2.1运行了4.0.4的DJ