AjaxDatatablesRails::AltApi
This is an alternative API to the ajax-datatables-rails gem. The motivation for this was that we had a lot of datatables written against an older version of ajax-datatables-rails. The newer version of ajax-datatables-rails was incompatible with our older implementation of datatables, so it required a major refactor effort. There were certain things in the recent ajax-datatables-rails API felt redundant, and if a major refactor was needed, a reimagined API started to be developed.
This uses ajax-datatables-rails under the hood. Perhaps, this or something similar may influence future versions of ajax-datatables-rails.
This is compatible with ajax-datatables-rails. This is intended to replace needing to define methods like: view_columns
, data
, defining def_delgators
.
Features
There are some additional features this API provides.
- Makes it easy to define the column definitions in the client JS. The column definitions are based on the same definitions that you declare in the datatable.
- Cells rendering automatically can delegate to the record or view. So the cell rendering blocks can easily access method defined on the view or the record.
- Columns are defined once, with the goal of reducing redundancy.
- Debugging mismatch problems with jQuery datatables can be frustrating. There is some code to help debug these tricky situations. There are still many improvements that can be done with this, but it is a start.
Basic Usage
Inside your application datatable or the individual datatables, include the module.
class ApplicationDatatable < AjaxDatatablesRails::ActiveRecord
include AjaxDatatablesRails::AltApi
end
Example datatable:
class UserDatatable < ApplicationDatatable
base_model 'User'
# The default behavior is that the column is searchable, sortable, and renders the value.
column(:first_name)
# Column names can be arbitrary. This example references a relationship
# alternatively, the block can be more explicit { |user| user.company.name } or { record.company.name }
column(:company_name, source: 'Company.name') { company.name }
column(:address, display_only: true) { format_address(address) }
# This example auto uses both the view's `l` method and `updated_at` (from the user record)
column(:updated_at, searchable: false) { l(updated_at, :short) }
# In this example, `:links` is not tied to the record. So `display_only` is used so it is not searchable or sortable.
# You can call `record` in the block to refer to the record passed to the cell renderer.
column(:links, display_only: true) { link_to("Show", user_path(record)) }
# Assuming there is an address relationship to the user, you can expose searchable attributes this way.
search_only_attributes %w[Address.city
Address.state_name
Address.country
Address.country_name
Address.postal_code]
# methods not available to the view some method called by a cell renderer block
module CellMethods
def format_address(address)
# makes the address pretty
end
end
private
def get_raw_records
User.includes(:address)
end
end
Front-end usage
Newer versions of jQuery Datatables expects the columns to be defined when the table is initialized. This gem generates that info based on the definition in the datatable.
# users_controller.rb
class UsersController < ApplicationController
def index
@users_datatable = UserDatatable.new(params, view_context: view_context)
respond_to do |fmt|
fmt.html
fmt.json do
render json: @customer_datatable
end
end
end
end
// users/index.html.erb
<table id="users-datatable"
data-ajax-url=""
data-datatable-columns=<%= @users_datatable.js_columns %>>
<th>Name</th>
<th>Company</th>
<th>Address</th>
<th>Last updated</th>
<th>links</th>
</table>
<script>
$table = $('#users-datatable');
$table.DataTable({
ajax: $table.data('ajax-url'),
processing: true,
serverSide: true,
columns: $table.data('datatable-columns')
})
</script>
Column options
The column
method can take the following arguments:
option | type | required | default value | meaning |
---|---|---|---|---|
attr_name | String | yes | nil |
Name of attr. This can be arbitrary, and not reflective of attributes on a model |
source | Boolean | no | same attr on base model | Use this if the attr_name is not on the base_model and the column needs to be searchable or sortable |
sortable | Boolean | no | true |
Do you want the model to be sortable |
visible | Boolean | no | true |
Set to false if this should not be rendered |
searchable | Boolean | no | true |
Set to false if you don't want the column to be searched |
condition | Proc | no | true |
A truthy result of the proc will render the column. This is useful if you want to conditionally show a column |
cond | Symbol | no | default of datatables | This is passed through to ajax-datatables-rails. It is the SQL matcher search will use |
search_only | Boolean | no | true |
Shorthand option for do not display but make attr searchable |
display_only | Boolean | no | true |
Shorthand option for display but exclude from search |
cell_renderer | Block | no | nil |
This block is what renders cells. More info below |
Cell rendering
There are two options for this. Let the attr_name
return the value associated with the base_model
attribute. Or you can provide a block. The block can take an argument:
{ |current_record| current_record.name }
or no argument { name } will both behave the same. method_missing
is used to seamlessly delegate to the record
, view
, or CellMethods defined on the datatable.
Testing
Tests are currently, non-existent 😕. It is something I'd like to change, but I doubt will have time. This was extracted from a rails project that had around 20 complex datatables. I feel that this has been put through its paces by working for the project this was extracted from. Tests were written against that project, but since datatables is closely tied with ActiveRecord. I'd like to write tests, but so far have not had the time.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake spec
to run the tests. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ajax-datatables-rails-alt-api.