Как хранить и разбивать XML-данные в виде модели Rails

У меня есть XML-канал, который я загружаю и анализирую в своем приложении Rails. Я начал реализовывать ее как библиотеку в lib/, но мне показалось более логичным рассматривать ее как модель. Для удобства я рассматриваю его как модель ActiveRecord. Требование состоит в том, чтобы он был совместим с плагином mislav will_paginate, хотя именно здесь у меня возникла проблема.

Я создал класс в app/models/, который наследуется от ActiveRecord::Base, и просто переопределяет метод поиска по умолчанию. Если есть более простой способ, я весь внимание. Но это работает.

class Job < ActiveRecord::Base
  def self.columns() @columns ||= []; end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

  column :title, :string
  column :company, :string

  def self.find(*args)
    url = "http://example.com"

    xml = Net::HTTP.get_response(URI.parse(url)).body
    doc = REXML::Document.new(xml)

    if args.first.to_s == 'all'
      results = Array.new

      doc.elements.each('response/results/result') do |r|
        job = self.new(
          :title => r.elements['jobtitle'].text,
          :company => r.elements['company'].text
        )

        results.push(job)
      end

      results
    end
  end
end

Итак, после этой работы следующим шагом будет попытка разбиения коллекции на страницы. Для этого я пытаюсь использовать will_paginate mislav, так как я использую этот плагин для своих типичных моделей. Проблема в том, что will_paginate пытается подсчитать общее количество заданий. Для этого он автоматически запускает «SELECT count(*) AS count_all FROM jobs». Конечно, это не удается, поскольку такой таблицы не существует.

Есть ли простой способ исправить эту проблему без изменения кода will_paginate, но при этом позволить стандартным моделям нормально использовать will_paginate?


person Jared Brown    schedule 18.01.2010    source источник


Ответы (1)


Вы можете довольно легко сделать любую коллекцию разбиваемой на страницы (?).

Array.class_eval do
  def paginate(page = 1, per_page = 10)
    WillPaginate::Collection.create(page, per_page, size) do |pager|
      pager.replace self[pager.offset, pager.per_page].to_a
    end
  end
end

Этот код сопоставляет массив с WillPaginate::Collection — параметр size, по сути, представляет собой количество записей.

Вы можете либо реализовать что-то подобное в своей модели, либо не использовать ActiveRecord... нет реальной причины, если вы не собираетесь использовать проверки и другие вещи в будущем.

person Toby Hede    schedule 19.01.2010