Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reports without DB table #722

Open
deep021985 opened this issue Feb 8, 2024 · 5 comments
Open

Reports without DB table #722

deep021985 opened this issue Feb 8, 2024 · 5 comments

Comments

@deep021985
Copy link

ActiveScaffold necessitates a table for all reports. Although we currently truncate and store data in a table before accessing it on each request, I acknowledge that this approach leads to data conflicts during simultaneous requests. Unfortunately, I haven't found an alternative yet. Please advise on how to develop reports without relying on a table.

@scambra
Copy link
Member

scambra commented Feb 8, 2024

ActiveScaffold is designed to work with ActiveRecord models, and has some support for Mongoid models too. However, some support was added to display data coming from other sources, which works creating a model which inherit from ActiveScaffold::Tableless, so it acts as ActiveRecord, you have to write the methods to find data or create data, depending on the actions you need to support. I'm not sure what kind of data you are truncating and storing in a table, but you could give a try. I didn't wrote a doc, although there is a model in test directory:
https://github.com/activescaffold/active_scaffold/blob/eb64dac2f51e815e0e588d4c803768103e3b1070/test/mock_app/app/models/file_model.rb

Someone added another way to the wiki: https://github.com/activescaffold/active_scaffold/wiki/Using-Active-Scaffold-On-A-Data-Structure-%E2%80%93-No-Database-Table

@deep021985
Copy link
Author

deep021985 commented Feb 8, 2024

I updated my model with new code using Tableless. Now getting error:

ActionView::Template::Error (self.execute_simple_calculation must be implemented in a Tableless model to support sum text_field2 columns):

3: <tr id="<%= active_scaffold_calculations_id %>" class="active-scaffold-calculations">
4:   <% columns.each do |column| -%>
5:     <% if column.calculation? %>
6:     <td id="<%= active_scaffold_calculations_id(:column => column) %>"><%= render_column_calculation(column) %></td>
7:     <% else %>
8:     <td>&nbsp;</td>
9:     <% end -%>

Model

class Report < ActiveScaffold::Tableless

  #column :id, :integer
  column :text_field1, :string 
  column :text_field2, :string
  column :text_field3, :string 
  column :text_field4, :string 
  column :text_field5, :string 
  column :text_field6, :string 
  column :text_field7, :string 
  column :text_field8, :string 
  column :text_field9, :string
  column :text_field10, :string 
  column :text_field11, :string 
  column :text_field12, :string 
  column :text_field13, :string 
  column :text_field14, :string 
  column :text_field15, :string 
  column :int_field1, :string 
  column :date_field1, :string 
  column :datetime_field1, :string
  column :person_id, :integer
  #self.primary_key = :id

  def destroy
    true
  end
end

Controller:

class ReportsController < ApplicationController
before_action :report_setup 

  active_scaffold :report do |config|
  
  config.list.columns = [:text_field1,  :int_field1]
  config.actions.exclude :create, :update, :delete
  config.action_links.add 'export', :action => 'export_xls',
	  :page => true, :label => "Export to Excel", :weight => 2
   config.search.link.weight = 3	   
	 
end	

def report_setup
	#clear session before action
	#session[:report_name] = session[:select] = session[:show_fields] = nil
		
   #get building_structure_ids 
   if session[:role_id] != 1	  
	active_scaffold_config.action_links.add 'reports', :controller => "menu", :action => 'reports',
	   :page => true, :label => "All Reports", :weight => 1
   end	  
   
   building_structure_ids = BuildingStructure.where("sublocation_code in (?)",  session[:sublocation_filter].split(",").compact.collect(&:strip)).pluck('id') 
   location_ids = Location.where("sublocation_code in (?)",  session[:sublocation_filter].split(",").compact.collect(&:strip)).pluck('id') 
   
   case params[:s] 
	when "typewise"
		active_scaffold_config.label = 'Asset type wise count'
		active_scaffold_config.list.columns	= [:text_field1,  :text_field2, :text_field3, :text_field4, :text_field5]	
		active_scaffold_config.columns[:text_field1].label = 'Asset type'
		active_scaffold_config.columns[:text_field2].label = 'Count'
		active_scaffold_config.columns[:text_field3].label = 'Working'
		active_scaffold_config.columns[:text_field4].label = 'Non working'
		active_scaffold_config.columns[:text_field5].label = 'Under repair'
		active_scaffold_config.columns[:text_field2].calculate = :sum
		active_scaffold_config.columns[:text_field3].calculate = :sum
		active_scaffold_config.columns[:text_field4].calculate = :sum
		active_scaffold_config.columns[:text_field5].calculate = :sum
		session[:report_name]	= 'AssetTypewiseCount'
		session[:select] = 'text_field1 as Asset_Type, text_field2 as Count,  text_field3 as Working, text_field4 as Non_Working, text_field5 as Under_Repair'
		session[:show_fields] = [:Asset_Type, :Count, :Working, :Non_Working, :Under_Repair]		
		
		report_setup_asset_typewise(building_structure_ids)	

		
   end
end
  	
def report_setup_asset_typewise(building_structure_ids)
		c_assets = AssetType.joins(asset_masters: :computer_assets).
		where("computer_assets.building_structure_id in (?)",  building_structure_ids).
		select("asset_types.asset_type_name as asset_type, computer_assets.current_status as status, count(computer_assets.current_status) as status_count").
		group("asset_type,status")
		
		p_assets = AssetType.joins(asset_masters: :printer_assets).
		where("printer_assets.building_structure_id in (?)",  building_structure_ids).
		select("asset_types.asset_type_name as asset_type, printer_assets.current_status as status, count(printer_assets.current_status) as status_count").
		group("asset_type,status")
		
		n_assets = AssetType.joins(asset_masters: :network_assets).
		where("network_assets.building_structure_id in (?)",  building_structure_ids).
		select("asset_types.asset_type_name as asset_type, network_assets.current_status as status, count(network_assets.current_status) as status_count").
		group("asset_type,status")
		
		ActiveRecord::Base.connection.execute("TRUNCATE reports") #Empty the report table first
		
		cgrp = c_assets.all.group_by(&:asset_type)
		pgrp = p_assets.all.group_by(&:asset_type)
		ngrp = n_assets.all.group_by(&:asset_type)
		create_asset_type_report(cgrp)
		create_asset_type_report(pgrp)
		create_asset_type_report(ngrp)		
end
   	
	
def create_asset_type_report(obj)
		obj.each do |k, v|
			tot = 0
			r = Report.new do |reprt|
				reprt.text_field1 		= 	k
				v.each do |record|
				if record.status == 'Working'	
					reprt.text_field3 = record.status_count.to_s  
				elsif record.status == 'Non Working'	
					reprt.text_field4 = record.status_count.to_s
				elsif record.status == 'Under Repair'	
					reprt.text_field5 = record.status_count.to_s
				end	
				tot = tot + record.status_count
				end	
				reprt.text_field2 = tot.to_s #total count of asset
				
				reprt.text_field3 = '0' if reprt.text_field3 == nil
				reprt.text_field4 = '0' if reprt.text_field4 == nil
				reprt.text_field5 = '0' if reprt.text_field5 == nil							
			end
			r.save
		end  
end 
  
end 

@scambra
Copy link
Member

scambra commented Feb 11, 2024

The error is saying you have to define self.execute_simple_calculation in Report model, as ActiveScaffold is trying to calculate counts, as you set calculate on some columns.

@deep021985
Copy link
Author

The absence of data structures like result objects and arrays impedes robust reporting, hampering agile development practices. Implementing these structures would significantly improve data organization and accessibility, leading to enhanced reporting functionalities and streamlined decision-making

@scambra
Copy link
Member

scambra commented Feb 15, 2024

Sorry, I don't know what you mean or trying to achieve. ActiveScaffold is focused in Rails and ActiveRecord, which is default ORM for rails. If you want to use ActiveScaffold to list or create data which is not in a ActiveRecord model, it won't be easy. I have used Tableless to list some data, e.g. got from api or got from files, but it's just a basic ActiveRecord class where you have to define methods to return data so ActiveScaffold can list them. If it's too hard, you can always use ActiveScaffold in other controllers, and build your own code for the reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants