首页 > 解决方案 > 在 Rails 中加入具有活动存储的多个表

问题描述

我在加入 2 个表时遇到问题。我习惯于主动存储保存文件。但我加入了 2 张桌子,但它不起作用。我正在加入产品账单。

这是比尔模型:

class Bill < ApplicationRecord
    belongs_to :product
end

这是产品型号

class Product < ApplicationRecord
  has_one_attached :image
  has_many :bills
  def new

  end
  def list
  end
end

我正在使用命令执行表 Products

Product.all

然后结果

[#<Product:0x00007f3d68ee4998
  id: 22,
  created_at: Tue, 25 May 2021 14:16:11.732340000 UTC +00:00,
  updated_at: Tue, 25 May 2021 14:16:11.775029000 UTC +00:00,
  name: "Bánh aghahhhahgha",
  des: "fgkagjagaahghahaghhah",
  money: 2000000.0,
  image: nil>]

image为零,因为活动存储保存了它。

我正在用命令执行 Bill 表

Bill.all

这是结果

[#<Bill:0x00007f3d68875008
  id: 8,
  user_id: 1,
  status: nil,
  message: nil,
  created_at: Tue, 25 May 2021 14:32:24.182690000 UTC +00:00,
  updated_at: Tue, 25 May 2021 14:32:24.182690000 UTC +00:00,
  number_phone: "0328267412",
  quality: 3,
  money: 6000000.0,
  product_id: 22>]

我正在使用命令加入 2 个表

Bill.joins(:product).select('bills.*, products.image a
s image, products.name as name')

结果

[#<Bill:0x0000556da2ce7ba0
  id: 8,
  user_id: 1,
  status: nil,
  message: nil,
  created_at: Tue, 25 May 2021 14:32:24.182690000 UTC +00:00,
  updated_at: Tue, 25 May 2021 14:32:24.182690000 UTC +00:00,
  number_phone: "0328267412",
  quality: 3,
  money: 6000000.0,
  product_id: 22>]

任何解决方案,请帮助我!.

标签: mysqlruby-on-rails

解决方案


当你执行

bill = Bill.joins(:product).select('bills.*, products.image a
s image, products.name as name')

它实际上是在尝试从产品表中的图像列加载数据。Active Record 不是这样工作的。当我们编写时,has_one_attached :image我们没有将它与产品表image列绑定,它声明了与active_storage_attachments表的一个关联。


这里是解释。

has_one_attached :imageproduct,这是表和表之间的关系active_storage_attachments

当我们运行rails active_storage:install这些迁移时,它们会被添加到应用程序中。

所以实际的关系是

class Bill
  belongs_to :product
end

and

class Product
  has_one :image
end

Note: (`image` for us to access, the real table name is `active_storage_attachments`)

现在你想要的查询是这样的,通过加入产品来返回图像。

=> bill = Bill.joins(:product).joins("INNER JOIN active_storage_attachments on active_storage_attachments.record_id = products.id and active_storage_attachments.record_type = 'Product'").select('bills.*, active_storage_attachments.* as image, products.name as name'))

=> bill.image
#<ActiveStorage::Attached::One:0x00007f911d8a2540
 @name="image",
 @record=
  #<Product:0x00007f911dadf448
   id: 1,
   ...

bill.image在上面的示例中将返回图像记录,它看起来像这样。但它不会执行额外的查询来加载图像,所以不用担心。

在前端访问图像

<%= image_tag url_for(bill.image) %>

这是 ActiveStorage 的完整指南https://edgeguides.rubyonrails.org/active_storage_overview.html#what-is-active-storage-questionmark


推荐阅读