Я использую этот гем для интеграции datatables:
gem 'jquery-datatables'
У меня есть возврат json из моего приложения, в котором есть 500 записей. То, что возвращается в браузер, генерируется в assets_datatable.rb:
class AssetsDatatable
delegate :params, :h, :link_to, :number_to_currency, to: :@view
delegate :url_helpers, to: 'Rails.application.routes'
def initialize(view)
@view = view
end
def as_json(options = {})
{
sEcho: params[:sEcho].to_i,
iTotalRecords: Asset.count,
iTotalDisplayRecords: assets.total_entries,
bServerSide: true,
aaData: data
}
end
private
def data
assets.map do |asset|
[
asset.id,
link_to(asset.title_paid,asset),
content_paid_fix(asset.movie_paid),
get_fw_id(asset),
get_fw_external_id(asset),
asset.pid,
asset.created_at.in_time_zone('Eastern Time (US & Canada)').to_s.gsub('-0400',''),
asset.lws.to_s.gsub('UTC',''),
asset.lwe.to_s.gsub('UTC',''),
asset.nil? ? 'None' : asset.status,
ApiCall.where(asset_id: asset.id)[0].nil? ? 'None' : ApiCall.where(asset_id: asset.id)[0].status,
TranscodeStatus.where(creative_id: ApiCall.where(asset_id: asset.id)[0].fw_id)[0].nil? ? 'Unknown' : TranscodeStatus.where(creative_id: ApiCall.where(asset_id: asset.id)[0].fw_id)[0].transcode_status
]
end
end
def content_paid_fix(paid)
if (paid.nil?)
return "None"
end
return paid
end
def get_fw_id(asset)
string_of_ids = ""
ApiCall.where(asset_id: asset.id).each do |line|
string_of_ids += line.fw_id.to_s + ","
end
if string_of_ids.gsub(",","") == ""
return "None"
else
return string_of_ids[0...string_of_ids.length - 1]
end
end
def get_fw_external_id(asset)
string_of_ids = ""
ApiCall.where(asset_id: asset.id).each do |line|
string_of_ids += line.fw_external_id.to_s + ","
end
if string_of_ids.gsub(",","") == ""
return "None"
else
return string_of_ids[0...string_of_ids.length - 1]
end
end
def assets
@assets ||= fetch_assets
end
def fetch_assets
assets = Asset.order("#{sort_column} #{sort_direction}")
assets = assets.page(page).per_page(per_page)
if params[:sSearch].present?
assets = assets.where("title_paid like :search or category like :search", search: "%#{params[:sSearch]}%")
end
assets
end
def page
params[:iDisplayStart].to_i/per_page + 1
end
def per_page
params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : Asset.count
end
def sort_column
columns = %w[title_paid]
columns[params[:iSortCol_0].to_i]
end
def sort_direction
params[:sSortDir_0] == "desc" ? "desc" : "asc"
end
end
В моем контроллере у меня есть:
def index
@assets = Asset.all
respond_to do |format|
format.html
format.json { render json: ::AssetsDatatable.new(view_context) }
end
На мой взгляд:
$(document).ready(function() {
var table = $('#assets').DataTable();
} );
Моя проблема в том, что производительность плачевна. Если я получаю доступ к JSON непосредственно из приложения по адресу: http://localhost:3000/ads/index.json
Используя инструменты разработчика, я вижу, что для загрузки документа по этому URL требуется ~ 5 секунд. Это с bServerSide: правда. Я тоже пробовал настройку
bDeferRender: true (также в методе as_json asset_datatable.rb) ... ничего не происходит ... загрузка json по-прежнему занимает ~ 5 секунд.
Мой вопрос - как мне улучшить производительность? Мне кажется, что загрузка полных 500 в assets_datatable.rb не будет работать. Даже с включенной отложенной загрузкой и т. Д. - он все еще запускает SQL для получения 500 записей, и, должно быть, эта часть занимает слишком много времени.
Так тогда - как один GRADUALLY подает строки таблицы? Как я могу сделать это, когда, когда они нажимают «Далее» в datatable, он тянет следующие 10 или 15 или сколько угодно? Насколько я могу судить, такого примера в Интернете нет, что я нахожу довольно странным, поскольку я уверен, что это обычное дело для приложения rails.