我有4张桌子:
key: id, name
project: id, name
project_key: id, key_id, project_id
project_report: id, status, project_id, key_id
project_c_report: id, status, project_id, key_id, c_id
我想使用这些表生成报告: 输出应为:
Key.name, project_report.status, project_c_report.status
我能够通过从项目获取所有密钥并循环遍历
来实现此目的array = []
project.keys.each do |k|
p = ProjectReport.where(keyword_id: k, project_id: p.id).map(&:status)
c = ProjectCReport.where(keyword_id: k, project_id: p.id, c_id:1).map(&:status)
array << {name: k.name, pr: p, pcr: c}
end
array
问题是我做了很多选择而且一切都很慢,有人可以用更好的方式来帮助我。
谢谢
答案 0 :(得分:1)
找出数据库查询,然后直接从模型中查询数据库:
def records
connection = ActiveRecord::Base.connection
records = connection.select %Q {
SELECT key.name, project_report.status, project_c_report.status
FROM ...
JOIN ...
;
}
records
end
答案 1 :(得分:1)
首先,在DataBase中创建一个函数。这只是一个简短的例子,也是在PostgreSQL中完成的,但不应该有太多不同 来自MySQL,SQLServer等
Function get_myreport(key_id integer, project_id integer [As many params as you'd like the function to get))
pProject ALIAS FOR $1;
pKey ALIAS FOR $2;
BEGIN
CREATE TEMP TABLE IF NOT EXISTS tmp_project_report(id integer, project_name character varying, *All the values you want to see in the report);
TRUNCATE tmp_project_report;
INSERT INTO tmp_project_report(all the columns)
SELECT a.table1_fields, b.table2_fields, c.table3_fields, d.table4_fields, e.table5_fields
FROM table1 a, table2 b, table3 c, table4 d, table5 e
WHERE
a.key = pKey
AND b.project_key = pProject
END;
然后,在你的控制器方法中,你可以像这样调用函数
myFunction = ActiveRecord:Base.connection.execute = "Select get_myreport("param1, param2, etc...")
您必须创建一个模型,其中放置了您所创建的temp_table上的所有字段,并且还将temp_table设置为self.table_name
然后,在您看来,您只需要对您的收藏进行迭代并相应地显示值
@report = TempTable.all
<% @report.each_do |report| %>
<% report.value1 %>
<% etc... %>
<% end %>
答案 2 :(得分:1)
如果您选择将其保留在Rails中,可以尝试以下内容(请注意,以下查询未经测试且仅针对概念显示):
report_data = Project.joins(project_key: :key)
.joins('left join project_reports on project_keys.project_id = project_reports.project_id and project_keys.key_id = project_reports.key_id
left join project_c_reports on project_keys.project_id = project_c_reports.project_id and project_keys.key_id = project_c_reports.key_id')
.where('project_c_reports.c_id = ?', 1)
.select('projects.name, project_reports.status as report_status, project_c_reports.status as c_report_status')
这应该为您提供一组Project
个对象,每个对象包含所选的三个属性name, report_status, c_report_status
。要在这三个元素的数组中获取这些值,您可以这样做:
report_data.map { |p| [ p.name, p.report_status, p.c_report_status ] }
查询的连接类型取决于您的要求。鉴于索引已经到位,查询应该与它在代码中的外观相比更好!