如何从多个表中获取数据并将它们与erb中的每个表一起转换
Posted
技术标签:
【中文标题】如何从多个表中获取数据并将它们与erb中的每个表一起转换【英文标题】:How to get data from multiple tables and turn them with each in erb 【发布时间】:2022-01-20 05:57:33 【问题描述】:想要实现
红宝石 2.6.5 轨道 6.0.3
感谢您的关注。 我正在使用 Rails 创建一个 Web 应用程序。
我想知道如何从多个表中只提取我想要的列的数据,将它们放入一个数组中,然后使用每个输出它们。
详情
我想从下表中提取相关的users.name、company.company_name和tasks.task_name,并将它们作为一个单元放入一个数组中。 我想输出我们以这种方式创建的数组,一次一个,使用erb中的每个。
像这样
・john Acompany task3
・white Dcompany task12
・carl Bcompany task8
・mark Ccompany task97
表格
用户表
id | name | sex | company_id |
---|---|---|---|
1 | john | 1 | 1 |
2 | white | 1 | 4 |
3 | carl | 1 | 2 |
4 | mark | 1 | 3 |
公司表
id | company_name | industry_1 | industry_2 |
---|---|---|---|
1 | Acompany | 3 | 9 |
2 | Bcompany | 6 | 10 |
3 | Ccompany | 1 | 3 |
4 | Dcompany | 4 | 8 |
任务表
id | task_name | company_id |
---|---|---|
1 | task3 | 1 |
2 | task12 | 4 |
3 | task97 | 3 |
4 | task8 | 2 |
试过
我认为我可以将每个元素打包到一个数组中,如下所示。但是实在想不出怎么实现,所以放弃了。
user_name = []
users.each do |user|
user_name << user.name
end
【问题讨论】:
【参考方案1】:您可以使用 ActiveRecord 中的 joins
方法并使用 pluck
获取您要查找的列:
user_details = User.joins(company: :tasks).pluck("users.name", "companies.company_name", "tasks.task_name")
#=> [["john", "Acompany", "task3"], ["white", "Dcompany", "task12"], ...]
接下来,遍历从上述代码返回的数组数组,以您想要的方式显示数据。请记住,在您的数据库架构中,有一个公司 has_many
任务,因此如果该公司有多个任务,您最终可能会为同一家公司提供多个数组。
user_details.each do |user_detail|
puts "・ " + user_detail.join(" ")
end
基于max 评论的其他(和首选)解决方案:
User.includes(company: :tasks).each do |user|
# Here you can retrieve and display the data you need using user.name, user.company.name, user.company.tasks
end
【讨论】:
应该注意的是,虽然 pluck 对于某些性能关键的应用程序来说是一个很好的工具,但使用字符串数组通常不是构建 MVC 应用程序的好方法,因为你完全跳过了 M 并制作视图完成所有使所有数据有意义的工作。相反,您希望使用预先加载以及可能的装饰器或委托。 这是一个非常好的评论。那么您是否愿意建议类似User.includes(company: :tasks)
的内容并在视图中对其进行迭代?我不太明白你关于“让视图完成所有工作以理解所有数据”的观点,你介意详细说明一下吗?
是的,我愿意。通过使视图完成工作,我的意思是您正在编写 user[0]
而不是 user.name
并且如果您必须处理任何不只是简单字符串(如日期)的列,或者从这个示例中您的视图必须处理的性别理解数据库中的原始数据。【参考方案2】:
这不是一个好主意。通过将数组从控制器传递到视图,您将完全跳过模型层并跳过它在反序列化和封装(以及更多)方面提供的所有内容。处理简单的数组也会破坏代码的可读性:
# which one of these was what now?
<tr>
<td><%= data[0] %></td>
<td><%= data[1] %></td>
</tr>
它毕竟是一个用面向对象语言构建的 MVC 框架。你的代码不应该是这样的。
相反,您可以使用预先加载和委托:
class User < ApplicationRecord
belongs_to :company
delegate :name, to: :company, prefix: true
end
@users = User.eager_load(:company)
.all
<table>
<thead>
<tr>
<th>Name</th>
<th>Company</th>
</tr>
</thead>
<tbody>
<%= @users.each do |user| %>
<tr>
<td><%= user.name %></td>
<td><%= user.company_name %></td>
# ...
</tr>
</tbody>
<% end %>
在某些情况下,您可能希望使用joins
来仅通过以下方式从关联中选择单个列或聚合:
class UsersController
def index
@users = User.joins(:company)
.select(
'users.*', 'companies.name AS company_name'
)
end
end
当涉及到任务时,您必须弄清楚您想要实际显示的是什么。由于关联对于用户和公司来说很可能是多对多的,因此甚至不清楚应该列出哪个任务。他们都是?首先?最后一个?
【讨论】:
以上是关于如何从多个表中获取数据并将它们与erb中的每个表一起转换的主要内容,如果未能解决你的问题,请参考以下文章
EXCEL问题,如何在三个工作表中查找出同时出现在这三个工作表中的所有数据,并将数据显示出来
如何从一个表列中获取值,将它们与字符串连接并将它们插入另一个表中?