Вычисление диапазона строк в HTML-таблице вложенных ресурсов DataMapper - PullRequest
0 голосов
/ 16 апреля 2011

У меня есть устаревшая база данных, которая находится за действительно дрянным приложением PHP.Веб-приложение вызывает все виды проблем с базой данных, и мне просто нужен быстрый и грязный способ представления того, что хранится в базе данных, таким образом, чтобы мой клиент мог видеть, насколько серьезна проблема, поэтому я создалПриложение Sinatra + DataMapper, но у меня возникают проблемы с вычислением некоторых значений в представлении.

В конце я хочу следующую таблицу:

+++++++++++++++++++++++++++++++++++++++++++++
+ Profile + Registration + Signup + Payment +
+         +              +        +++++++++++
+         +              +        + Payment +
+         +              ++++++++++++++++++++
+         +              + Signup + Payment +
+         +++++++++++++++++++++++++++++++++++
+         + Registration + Signup + Payment +
+         +              ++++++++++++++++++++
+         +              + Signup +         + <- Signup w/ no payments
+++++++++++++++++++++++++++++++++++++++++++++
+ Profile + Registration + Signup + Payment +
+         +++++++++++++++++++++++++++++++++++
+         + Registration +        +         + <- Registration w/ no Signups
+++++++++++++++++++++++++++++++++++++++++++++
+ Profile +              +        +         + <- Profile w/ no Registrations
+++++++++++++++++++++++++++++++++++++++++++++

Моя первая проблема заключается в том, что этотребует тонны SQL-запросов [в основном (n + 1) * (n + 1) * (n + 1) * (n + 1)], но AFAIK нет способа заставить DataMapper быстро загружать вложенные модели, ниво всяком случае, кэшировать модель данных таким образом, чтобы сделать чтение более эффективным.(Я ничего не записываю обратно в БД, и снимок базы данных в порядке - на самом деле нет дела до живых обновлений).На данный момент это допустимо, потому что это однократный отчет.

Моя вторая проблема - вычисление диапазона строк для заданных столбцов.Сначала я просто использовал количество платежей для текущей области (profile.registrations.signups.payments.size, registration.signups.payments.size и т. Д.), Но, как вы можете видеть в первом примере выше, на самом деле платежа на один меньше, чем было бы необходимо иметьточный диапазон строк для профиля.

Единственное теоретическое решение, которое мне удалось найти, - это в основном циклически проходить каждый дочерний объект на каждом этапе, чтобы точно узнать, какие дочерние объекты доступны.за пределами этого шага, но это кажется действительно не элегантным и потребовало бы экспоненциального увеличения количества выполняемых SQL.

Есть ли какой-то другой способ, которым я могу подойти к этому?Я не женат на DataMapper или HAML, я просто хочу сделать это настолько эффективно, насколько это возможно.

Я вставляю свой текущий HAML и модели данных ниже для справки.

index.haml (я знаю, это неприятно)

#content
  %p #{@profiles.size} Profiles
  %table.display{:border=>1, :cellpadding=>2,:width=>'100%'}
    %thead
      %th Prof ID
      %th Profile
      %th Reg's
      %th Reg ID
      %th Registration
      %th Signups
      %th Event ID
      %th Event
      %th Event Date
      %th Payments
      %th Pmt ID
      %th Amt
      %th Pmt Date
    %tbody
      - @profiles.each do |profile|
        - profile_rowspan = [profile.registrations.signups.payments.size, profile.registrations.signups.size, profile.registrations.size, 1].detect { |i| i > 0 }
        %tr{:valign=>'top'}
          %td{:rowspan => profile_rowspan, :class => "profile"} #{profile.id}
          %td{:rowspan => profile_rowspan} #{profile.firstname} #{profile.lastname}
          %td{:rowspan => profile_rowspan} #{profile.registrations.size}
          - if profile.registrations.size == 0
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
            %td{:rowspan => profile_rowspan}
          - profile.registrations.each_with_index do |registration, reg_index|
            - if reg_index != 0
              != "</tr><tr valign=\"top\">"
            - reg_rowspan = [registration.signups.payments.size, registration.signups.size, 1].detect { |i| i > 0 }
            %td{:rowspan => reg_rowspan, :class => "registration"} #{registration.id}
            %td{:rowspan => reg_rowspan} #{registration.firstname} #{registration.lastname}
            %td{:rowspan => reg_rowspan} #{registration.signups.size}
            - if registration.signups.size == 0
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
              %td{:rowspan => reg_rowspan}
            - registration.signups.each_with_index do |signup, signup_index|
              - if signup_index != 0
                != "</tr><tr valign=\"top\">"
              - signup_rowspan = [signup.payments.size, 1].detect { |i| i > 0 }
              %td{:rowspan => signup_rowspan, :class => "signup"} #{signup.event.id}
              %td{:rowspan => signup_rowspan} #{signup.event.event_title}
              %td{:rowspan => signup_rowspan} #{signup.event.event_start}
              %td{:rowspan => signup_rowspan} #{signup.payments.size}
              - if signup.payments.size == 0
                %td{:rowspan => signup_rowspan}
                %td{:rowspan => signup_rowspan}
                %td{:rowspan => signup_rowspan}
              - signup.payments.each_with_index do |payment, payment_index|
                - if payment_index != 0
                  != "</tr><tr valign=\"top\">"
                %td{:class => "payment"} #{payment.id}
                %td #{payment.total}
                %td #{payment.payment_date}

profile.rb

class Profile
  has n, :registrations
end

registration.rb

class Registration
  belongs_to :profile
  has n, :signups
  has n, :payments
end

signup.rb

class Signup
  belongs_to :registration
  belongs_to :event
  has n, :payments
end

payment.rb

class Payment
  belongs_to :registration
  belongs_to :signup
end

событие.руб

class Event
  has n, :signups
  has n, :payments, :through => :signups
end

1 Ответ

0 голосов
/ 17 апреля 2011

Если вы используете MySQL, он может возвращать результаты запроса в виде HTML. Стоит посмотреть, что он может сделать в качестве отправной точки.

Затем вы можете использовать Nokogiri, чтобы находить пустые ячейки и манипулировать HTML, как вы хотите.

...