How to write Rails Builder XML start and end tags without 'do'

162 Views Asked by At

I have a Staff model as follows (for brevity)

 id
 firstname
 lastname
 stafftype (e.g. Chef, Driver, Team Leader)

I also have a StaffTimePeriod model as follows

  id
  staffid
  date
  staffstatus  (e.g. Working, Holiday, Sick)

There is a StaffTimePeriod record for each day for each Staff member.

I have the correct associations setup which allows me to do the following:

@stps = StaffTimePeriod.includes(:staff).where('date >= ? and date <= ?',begofweek,endofweek).order('staff.firstname,staff.lastname,date')

So I now get all my StaffTimePeriods for a particular week sorted by the Staff name and date.

I need to produce an XML file for a particular week showing Staff Name, date, staffstatus in the following format.

<rows>
  <row>
    <cell>firstname+lastname</cell>
    <cell>stafftype</cell>
    <cell>date (for Monday )</cell>
    <cell>staffstatus (for Monday)</cell>
    <cell>date (for Tue )</cell>
    <cell>staffstatus (for Tue )</cell>
    <cell>date (for Wed)</cell>
    <cell>staffstatus (for Wed)</cell>
    <cell>date (for Thu )</cell>
    <cell>staffstatus (for Thu)</cell>
    <cell>date (for Fri)</cell>
    <cell>staffstatus (for Fri)</cell>
    <cell>date (for Sat)</cell>
    <cell>staffstatus (for Sat)</cell>
    <cell>date (for Sun)</cell>
    <cell>staffstatus (for Sun)</cell>
  </row>
  <row>
    <cell>firstname+lastname (Next Staff)</cell>
     ....
     ....
  </row>
</rows>

Within Builder I'm trying to iterate over the @stps BUT only output the Staff.firstname+lastname and Staff.stafftype on change of Staff.id

Here is my Builder code:

xml.instruct! :xml, :version => "1.0"
xml.tag!("rows") do
  tmpstaffid = nil
  weekdays = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
  @stps.each do |stp|
    if tmpstaffid != nil && tmpstaffid != stp.staff.id
      xml.tag!("/row")
    end
    if tmpstaffid != stp.staff.id
      xml.tag!("row", {"id" => stp.staff.id})
      xml.tag!("cell", stp.staff.fullname)
      xml.tag!("cell", stp.staff.stafftype)
      tmpstaffid = stp.staff.id
    end
    if weekdays.include?(stp.stpdate.strftime('%a'))
      xml.tag!("cell", stp.stpstatus)
    else
      xml.tag!('cell','')
    end
  end
end

However that is giving me the following output :

    <rows>
      <row id="4"/>
      <cell>Fname4 Lname4</cell>
      <cell>4</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      <cell>79</cell>
      </row/>
      <row id="5" />
      .....

      </row/>
    </rows>

As you can see the starting '<row>' also has a terminating /> included.

What I need is an XML tag which says this is a Starting XML tag and also an Ending XML tag which can be created independently instead of within a do ... end loop.

Can I define separate Starting and Ending XML tags independently of a 'do end' loop? If not, then how do I achieve the above?

0

There are 0 best solutions below