# lib/generators/datatables/USAGE
Description:
Creates the datatables structure for you.
Example:
rails generate datatables init
This will create:
app/services/datatables
app/services/datatables/application_datatable.rb
rails generate datatables users
This will create:
app/services/datatables
app/services/datatables/application_datatable.rb
app/services/datatables/users_datatable.rb
# lib/generators/datatables/datatables_generators.rb
class DatatablesGenerator < Rails::Generators::Base
source_root File.expand_path('../templates', __FILE__)
argument :model, type: :string
class_option :doc, type: :boolean, default: true, desc: "Include documentation."
def generate_init
generate_application_datatable
end
def generate_model
generate_model_datatable unless model == 'init'
end
private
def generate_application_datatable
copy_file 'datatable_template.template', 'app/services/datatables/application_datatable.rb'
end
def generate_model_datatable
template 'model_datatable_template.template', "app/services/datatables/#{model.underscore}_datatable.rb"
end
end
# lib/generators/datatables/templates/datatable_template.template
class ApplicationDatatable
# delegate :params, to: :@view
# delegate :link_to, to: :@view
def initialize(view)
@view = view
end
def as_json(options = {})
{
recordsTotal: count,
recordsFiltered: total_entries,
data: data
}
end
private
def page
params[:start].to_i/per_page + 1
end
def per_page
length > 0 ? length : 10
end
def sort_column
columns[params[:order]['0'][:column].to_i]
end
def sort_direction
params[:order]['0'][:dir] == "desc" ? "desc" : "asc"
end
def length
params[:length].to_i
end
end
# lib/generators/datatables/templates/model_datatable_template.template
class <%= model.camelcase %>Datatable < ApplicationDatatable
delegate :edit_<%= model.singularize.downcase %>_path, to: :@view
private
<%- if options.doc? -%>
# Loop through memoized collection and build the columns.
# If extracting from a view, be sure to add delegates
# and to also clean up and inject each column into the column var.
# Also, if you have multiple items (links) in a single column, you
# will need to create a separate variable and join them accordingly
# when pushing to the column array
<%- end -%>
def data
<%= model.downcase.pluralize %>.map do |<%= model.downcase.singularize.underscore %>|
[].tap do |column|
column << nil # something
end
end
end
<%- if options.doc? -%>
# Returns the count of records.
<%- end -%>
def count
<%= model.singularize.camelcase %>.count
end
def total_entries
<%= model.downcase.underscore %>.total_count
# will_paginate
# <%= model.downcase.underscore %>.total_entries
end
def <%= model.downcase.underscore %>
@<%= model.downcase.underscore %> ||= fetch_<%= model.downcase.underscore %>
end
def fetch_<%= model.downcase.underscore %>
search_string = []
columns.each do |term|
search_string << "#{term} like :search"
end
# will_paginate
# <%= model.downcase.underscore %> = <%= model.singularize.camelcase %>.page(page).per_page(per_page)
<%= model.downcase.underscore %> = <%= model.singularize.camelcase %>.order("#{sort_column} #{sort_direction}")
<%= model.downcase.underscore %> = <%= model.downcase.underscore %>.page(page).per(per_page)
<%= model.downcase.underscore %> = <%= model.downcase.underscore %>.where(search_string.join(' or '), search: "%#{params[:search][:value]}%")
end
<%- if options.doc? -%>
# The columns needs to be the same list of searchable items and IN ORDER that they will appear in Data.
<%- end -%>
def columns
%w()
end
end