views:

24

answers:

1

Hello, I am currently trying to read from an xml file which records the jobs on a PBS. I have succesfullly managed to parse the code, but am unable to insert the objtects into my database, i receive this error:

"You have a nil object when you didn't expect it! You might have expected an instance of ActiveRecord::Base. The error occurred while evaluating nil.delete"

This is my Model:

require 'xml/libxml'

class Job < ActiveRecord::Base

  JOB_DIR = File.join('data', 'jobs')

  attr_reader :jobid, :user, :group, :jobname, :queue, :ctime
  attr_reader :qtime, :etime, :start, :owner

  def initialize(jobid, user, group, jobname, queue, ctime, qtime, etime, start, owner)
    @jobid, @user, @group, @jobname, @queue = jobid, user, group, jobname, queue
    @ctime, @qtime, @etime, @start, @owner = ctime, qtime, etime, start, owner
  end

  def self.find_all()
    jobs = []
    input_file = "#{JOB_DIR}/1.xml"
    doc = XML::Document.file(input_file) 
    doc.find('//execution_record').each do |node| 
      jobs << Job.new(
        node.find('jobid').to_a.first.content,
        node.find('user').to_a.first.content,
        node.find('group').to_a.first.content,
        node.find('jobname').to_a.first.content,
        node.find('queue').to_a.first.content,
        node.find('ctime').to_a.first.content,
        node.find('qtime').to_a.first.content,
        node.find('etime').to_a.first.content,
        node.find('start').to_a.first.content,
        node.find('owner').to_a.first.content

      )
    end
    jobs
  end
end

An my Model Controller:

class JobController < ApplicationController

  def index
    @jobs = Job.find_all()
  end

  def create
    @jobs = Job.find_all()
    for job in @jobs
      job.save
    end
  end

end

I would appreciate any help...Thank you!

+1  A: 

I'm not sure on the causes of the error message you're seeing because I can't see anywhere that you're trying to invoke a delete method, however this does seem like a slightly confused use of ActiveRecord.

If you have a jobs database table with fields jobid, user, group, jobname etc. then ActiveRecord will create accessor methods for these and you should not be using attr_reader or overriding initialize. You should also not be setting values value instance variables (@jobid etc.) If you don't have such fields on your table then there is nothing in your current code to map the values from the XML the database fields.

Your def self.find_all method should probably be along the lines of:

def self.build_from_xml
  jobs = []
  input_file = "#{JOB_DIR}/1.xml"
  doc = XML::Document.file(input_file) 
  doc.find('//execution_record').each do |node| 
    jobs << Job.new(
      :jobid => node.find('jobid').to_a.first.content,
      :user => node.find('user').to_a.first.content,
  ...

Rails used to have a method of its own find_all to retrieve all existing records from the database so your method name is probably a bit misleading. Rails tends to use the build verb to mean create a new model object but don't save it yet so that's why I've gone with a name like build_from_xml.

mikej
Thank you Mikej, This was very helpful!
jalagrange
@jalagrange I know you have accepted the answer but I don't feel I've helped you that much - feel free to post any follow up questions when you get a bit further.
mikej