From f62ce572795b52c98d44a6198680e17c991bc396 Mon Sep 17 00:00:00 2001 From: bionickatana Date: Tue, 28 Jul 2026 22:05:33 -0600 Subject: [PATCH] Mostly working state --- app/controllers/dashboard_controller.rb | 42 +++- app/models/joint_info.rb | 5 + app/models/joints_info.rb | 5 - app/views/dashboard/index.html.erb | 179 +----------------- config/dashboard_manifest.yml | 44 +++-- test/controllers/dashboard_controller_test.rb | 13 +- 6 files changed, 79 insertions(+), 209 deletions(-) create mode 100644 app/models/joint_info.rb delete mode 100644 app/models/joints_info.rb diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 22d55ca..0d7a6f6 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -1,5 +1,18 @@ require 'yaml' + +## Debugging: +# If the response should be filtered and it is not being filtered **and** you +# are geting all the values for that column, check to make sure that you are +# selecting from the allowed tables and columns. + + +ALLOWED_TABLES = { + "JointInfo" => ["Joint", "Osteokinematics"], + "Joint" => ["Common Name", "Joint"] +} + + class DashboardController < ApplicationController before_action :load_manifest @@ -13,14 +26,28 @@ class DashboardController < ApplicationController # GET /dashboard/options?table=Joint&filter_col=joint_id&value=1 def options - table = params[:table].constantize - if params[:filter_col].present? - options = table.where(params[:filter_col] => params[:value]).pluck(params[:pluck_column]) + # 1. Define what is allowed to be accessed + + table_name = params[:table] + col_name = params[:pluck_column] + + # 2. Validate that the table and column exist in your allowlist + if ALLOWED_TABLES.key?(table_name) && ALLOWED_TABLES[table_name].include?(col_name) + table = table_name.constantize + quoted_col = ActiveRecord::Base.connection.quote_column_name(col_name) + + if params[:filter_column].present? && ALLOWED_TABLES[table_name].include?(params[:filter_column]) + puts "Filtering with 'filter_column'" + options = table.select(Arel.sql(quoted_col)).where(params[:filter_column] => params[:value]).pluck(Arel.sql(quoted_col)) + else + puts "***NO FILTERING***" + options = table.distinct.pluck(Arel.sql(quoted_col)) + end + + render json: options else - puts table - options = table.distinct.pluck(params[:pluck_column]) + render json: { error: "Invalid table or column requested" }, status: :bad_request end - render json: options end # GET /dashboard/data?joint=Acromioclavicular&sub_joint=X @@ -29,10 +56,11 @@ class DashboardController < ApplicationController # Use the data_sources from YAML to aggregate data @manifest['data_sources'].each do |source| + debugger table = source['table'].constantize # Find the filter value from the params that matches the filter_column # We assume the filter_column name in DB matches the filter ID in YAML - filter_val = params[source['filter_column']] || params['joint'] # Fallback to joint + filter_val = params[source['filter_column']] record = table.find_by(source['filter_column'] => filter_val) results[source['key']] = record ? record.attributes : {} diff --git a/app/models/joint_info.rb b/app/models/joint_info.rb new file mode 100644 index 0000000..d1652eb --- /dev/null +++ b/app/models/joint_info.rb @@ -0,0 +1,5 @@ +class JointInfo < ApplicationRecord + def readonly? + true + end +end diff --git a/app/models/joints_info.rb b/app/models/joints_info.rb deleted file mode 100644 index eceaad6..0000000 --- a/app/models/joints_info.rb +++ /dev/null @@ -1,5 +0,0 @@ -class JointsInfo < ApplicationRecord - def readonly? - true - end -end diff --git a/app/views/dashboard/index.html.erb b/app/views/dashboard/index.html.erb index 5c448f6..500d8c9 100644 --- a/app/views/dashboard/index.html.erb +++ b/app/views/dashboard/index.html.erb @@ -18,180 +18,6 @@ .bg-pale-orange { background-color: #FCE4D6; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -