Merge branch 'filter-datatables' of https://github.com/ZeusWPI/Tab into filter-datatables
This commit is contained in:
commit
331f00191e
3 changed files with 129 additions and 53 deletions
|
@ -1,52 +1,52 @@
|
||||||
|
class DataTable
|
||||||
|
|
||||||
module DataTable
|
def initialize user, params
|
||||||
extend ActiveSupport::Concern
|
@user = user
|
||||||
|
@params = sanitize_params(params)
|
||||||
|
@transactions = TransactionsQuery.new(@user)
|
||||||
|
@table = @transactions.arel_table
|
||||||
|
end
|
||||||
|
|
||||||
def apply_filter(user, params)
|
def json
|
||||||
params = sanitize_params(params)
|
response_json(@params[:draw], data)
|
||||||
selection = user.transactions
|
end
|
||||||
|
|
||||||
# filter time
|
def data
|
||||||
lower = params[:columns][:time][:lower]
|
ActiveRecord::Base.connection.execute(self.query.to_sql)
|
||||||
upper = params[:columns][:time][:upper]
|
end
|
||||||
if lower and upper
|
|
||||||
selection = selection.where(created_at: lower..upper)
|
|
||||||
elsif lower
|
|
||||||
selection = selection.where('created_at > :lower', lower: lower)
|
|
||||||
elsif upper
|
|
||||||
selection = selection.where('created_at < :upper', upper: upper)
|
|
||||||
end
|
|
||||||
|
|
||||||
# filter amount TODO this filters on absolute value
|
def query
|
||||||
lower = params[:columns][:amount][:lower]
|
pred = predicates
|
||||||
upper = params[:columns][:amount][:upper]
|
q = @transactions.query
|
||||||
if lower and upper
|
q = q.where(pred) if pred
|
||||||
selection = selection.where(amount: lower..upper)
|
q
|
||||||
elsif lower
|
end
|
||||||
selection = selection.where('amount > :lower', lower: lower)
|
|
||||||
elsif upper
|
|
||||||
selection = selection.where('amount < :upper', upper: upper)
|
|
||||||
end
|
|
||||||
|
|
||||||
# filter peer # TODO peer.name
|
def predicates
|
||||||
peer = params[:columns][:peer][:value]
|
[ *range_predicates(:amount),
|
||||||
if peer
|
*range_predicates(:time),
|
||||||
selection = selection.where("(debtor_id = :id AND creditor_id LIKE :peer) OR (creditor_id = :id AND debtor_id LIKE :peer)", id: user.id, peer: "%#{peer}%")
|
eq_predicate(:peer),
|
||||||
end
|
eq_predicate(:issuer),
|
||||||
|
like_predicate(:message)
|
||||||
|
].compact.inject { |l, r| l.and(r) }
|
||||||
|
end
|
||||||
|
|
||||||
# filter issuer # TODO issuer.name
|
def range_predicates name
|
||||||
issuer = params[:columns][:issuer][:value]
|
col = @params[:columns][name]
|
||||||
if issuer
|
[
|
||||||
selection = selection.where("issuer_id LIKE :re", re: "%#{issuer}%")
|
(@table[:name].gteq(col[:lower]) if col[:lower]),
|
||||||
end
|
(@table[:name].lteq(col[:upper]) if col[:upper])
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
# filter message
|
def eq_predicate name
|
||||||
message = params[:columns][:message][:value]
|
value = @params[:columns][:name][:value]
|
||||||
if message
|
@table[:name].eq(value) if value
|
||||||
selection = selection.where("message LIKE :re", re: "%#{message}%")
|
end
|
||||||
end
|
|
||||||
|
|
||||||
selection_to_json(user, params[:draw], selection)
|
def like_predicate name
|
||||||
|
value = @params[:columns][:name][:value]
|
||||||
|
@table[:name].matches("%#{value}%") if value
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -78,18 +78,19 @@ module DataTable
|
||||||
return clean
|
return clean
|
||||||
end
|
end
|
||||||
|
|
||||||
def selection_to_json(user, draw, selection)
|
def response_json(draw, selection)
|
||||||
{
|
{
|
||||||
draw: draw,
|
draw: draw,
|
||||||
recordsTotal: user.transactions.count,
|
recordsTotal: @user.transactions.count,
|
||||||
recordsFiltered: selection.count,
|
recordsFiltered: selection.count,
|
||||||
data: selection.offset(params[:start]).take(params[:length]).map { |transaction| {
|
#data: selection.offset(params[:start]).take(params[:length]).map { |transaction| {
|
||||||
time: transaction.created_at,
|
#time: transaction.created_at,
|
||||||
amount: transaction.signed_amount_for(user),
|
#amount: transaction.signed_amount_for(user),
|
||||||
peer: transaction.peer_of(user).try(:name),
|
#peer: transaction.peer_of(user).try(:name),
|
||||||
issuer: transaction.issuer.name,
|
#issuer: transaction.issuer.name,
|
||||||
message: transaction.message,
|
#message: transaction.message,
|
||||||
}}
|
#}}
|
||||||
|
data: selection
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
74
app/controllers/concerns/transactions_query.rb
Normal file
74
app/controllers/concerns/transactions_query.rb
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
class TransactionsQuery
|
||||||
|
attr_reader :arel_table
|
||||||
|
|
||||||
|
def initialize user
|
||||||
|
@user = user
|
||||||
|
@transactions = Arel::Table.new(:transactions)
|
||||||
|
@perspectived = Arel::Table.new(:perspectived_transactions)
|
||||||
|
@peers = Arel::Table.new(:users).alias('peers')
|
||||||
|
@arel_table = Arel::Table.new(@user.name.concat('_transactions'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def query
|
||||||
|
Arel::SelectManager.new(ActiveRecord::Base)
|
||||||
|
.from(arel)
|
||||||
|
.project(Arel.star)
|
||||||
|
end
|
||||||
|
|
||||||
|
def arel
|
||||||
|
Arel::Nodes::TableAlias.new(
|
||||||
|
issued_by(User).union(:all, issued_by(Client)),
|
||||||
|
arel_table.name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def issued_by klass
|
||||||
|
issuers = klass.arel_table.alias('issuer')
|
||||||
|
Arel::SelectManager.new(ActiveRecord::Base)
|
||||||
|
.from(transactions)
|
||||||
|
.join(@peers).on(@peers[:id].eq(@perspectived[:peer_id]))
|
||||||
|
.join(issuers).on(issuers[:id].eq(@perspectived[:issuer_id]))
|
||||||
|
.where(@perspectived[:issuer_type].eq(klass.name))
|
||||||
|
.project(
|
||||||
|
@perspectived[:amount],
|
||||||
|
@perspectived[:time],
|
||||||
|
@perspectived[:message],
|
||||||
|
@peers[:name].as('peer'),
|
||||||
|
issuers[:name].as('issuer')
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def transactions
|
||||||
|
Arel::Nodes::TableAlias.new(
|
||||||
|
incoming.union(:all, outgoing),
|
||||||
|
@perspectived.name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def outgoing
|
||||||
|
@transactions
|
||||||
|
.where(@transactions[:debtor_id].eq(@user.id))
|
||||||
|
.project(
|
||||||
|
(@transactions[:amount]*Arel::Nodes::SqlLiteral.new("-1")).as('amount'),
|
||||||
|
@transactions[:creditor_id].as('peer_id'),
|
||||||
|
@transactions[:created_at].as('time'),
|
||||||
|
@transactions[:issuer_id],
|
||||||
|
@transactions[:issuer_type],
|
||||||
|
@transactions[:message]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def incoming
|
||||||
|
@user.incoming_transactions.arel
|
||||||
|
@transactions
|
||||||
|
.where(@transactions[:debtor_id].eq(@user.id))
|
||||||
|
.project(
|
||||||
|
@transactions[:amount],
|
||||||
|
@transactions[:debtor_id].as('peer_id'),
|
||||||
|
@transactions[:created_at].as('time'),
|
||||||
|
@transactions[:issuer_id],
|
||||||
|
@transactions[:issuer_type],
|
||||||
|
@transactions[:message]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,13 +1,14 @@
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
load_and_authorize_resource
|
load_and_authorize_resource
|
||||||
|
|
||||||
include DataTable
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@user = User.find(params[:id])
|
@user = User.find(params[:id])
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html
|
format.html
|
||||||
format.json { render json: apply_filter(@user, params) }
|
format.json do
|
||||||
|
datatable = DataTable.new(@user, params)
|
||||||
|
render json: datatable.json
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue