Forest Admin not working with Active Storage

Feature(s) impacted

Forest Admin is not working with every table that I have some active storage relationship. For example, this simple code makes the request for data fail. Removing the line makes Forest show all other columns.

class Deposit < ApplicationRecord
  has_one_attached :receipt_image
end

Rails generated schema:

  create_table "active_storage_attachments", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "name", null: false
    t.string "record_type", null: false
    t.uuid "record_id", null: false
    t.datetime "created_at", null: false
    t.uuid "blob_id", default: -> { "gen_random_uuid()" }, null: false
    t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
    t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
  end

  create_table "active_storage_blobs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
    t.string "key", null: false
    t.string "filename", null: false
    t.string "content_type"
    t.text "metadata"
    t.bigint "byte_size", null: false
    t.string "checksum", null: false
    t.datetime "created_at", null: false
    t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
  end

Observed behavior

Forest Admin always returns a 500 status code and no data.

{ "status": 500, "error":" Internal Server Error" }

Expected behavior

Forest Admin to show my models that have attachments.

Failure Logs

In browser: { “status”:500, “error”:" Internal Server Error" }
In server logs: public_send(/opt/render/project/.gems/ruby/3.0.0/gems/activestorage-6.0.5/lib/active_storage/attached/one.rb:13)

…

Request Data

curl --request GET 'https://api.usekamba.com/forest/Deposit?timezone=America%2FSao_Paulo&fields[Deposit]=account_id%2Caccount_type%2Camount%2Ccompany_bank_account%2Ccreated_at%2Ccurrency%2Cexpires_at%2Cid%2Cpayment_method_id%2Cpayout_at%2Creceipt_image%2Creceipt_image_attachment%2Creceipt_image_blob%2Creceipt_image_url%2Cstatus%2Ctransaction_type%2Cupdated_at&fields[company_bank_account]=id&fields[receipt_image_attachment]=name&fields[receipt_image_blob]=id&page[number]=1&page[size]=15&sort=-id' \
--header 'Cf-Worker:onrender.com' \
--header 'Accept-Language:en-US,en;q=0.9' \
--header 'Priority:u=1, i' \
--header 'Dnt:1' \
--header 'Version:HTTP/1.1' \
--header 'Cdn-Loop:cloudflare; subreqs=1' \
--header 'Cf-Connecting-Ip:201.17.125.96' \
--header 'Authorization:******' \
--header 'X-Request-Start:1684922767423448' \
--header 'Cf-Ew-Via:15' \
--header 'User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36' \
--header 'Render-Proxy-Ttl:4' \
--header 'Host:api.usekamba.com' \
--header 'Referer:https://app.forestadmin.com/' \
--header 'Cf-Ipcountry:BR' \
--header 'Sec-Ch-Ua:"Chromium";v="113", "Not-A.Brand";v="24"' \
--header 'Cf-Visitor:{"scheme":"https"}' \
--header 'Accept-Encoding:gzip' \
--header 'Sec-Fetch-Site:cross-site' \
--header 'Sec-Fetch-Mode:cors' \
--header 'Sec-Ch-Ua-Platform:"macOS"' \
--header 'Sec-Ch-Ua-Mobile:?0' \
--header 'Cf-Ray:7cc4b95fc5452558-GIG' \
--header 'Sec-Fetch-Dest:empty' \
--header 'Origin:https://app.forestadmin.com' \
--header 'True-Client-Ip:201.17.125.96' \
--header 'X-Forwarded-For:201.17.125.96, 172.70.105.136' \
--header 'Accept:application/json' \
--header 'X-Forwarded-Proto:https' \
--header 'Content-Type:application/json' \
--cookie '__cf_bm=MHlGyoO_MBEvGkPpdYkA1yjOPIP2z6CU5sI53aDODoo-1684922122-0-AbtvCcyYQilqqEyDPJ8h0ryCgA2DK9K Sb9QATiX tyPi3Ydtdg67FccwfjFEb2rxYRBsZ/ vHDuBEd3WRD5qG8=;_cfuvid=ob_1lV2Vs7DU1kC_PajDxAoyPUxXmJCJeBOa6qrqfHg-1684922122086-0-604800000;'

Context

  • Project name: kamba-web
  • Team name: …
  • Environment name: Production, Development, SANDBOX
  • Agent (forest package) name & version: gem 'forest_liana', '8.0.8'
  • Database type: posgresql
  • Recent changes made on your end if any: Any.

I really need your help here guys as one of our main features needs to validate user bank receipts and our non-technical team is having a lot of problems validating these user-uploaded receipts in the dashboard. So far we are using JetAdmin but I like Forest and don’t want to migrate just because of this situation.

Thank you.

Hi @amarildo,

It seems that the service_name field is missing in your active_storage_blobs migration.

The problem occurs in all three environments ?

Can you share the error log ?

Hi @nicolasa thank you for your reply.

Yes, the problem occurs in all my environments including development. And I can reproduce all of them. It is not the service_name.

In this simple example and every other model that has the has_one_attached association, Forest fails to render the views.

class Bank < ApplicationRecord
  has_one_attached :logo # If I comment on this line Forest will work

  def aws_logo_url
    ENV['AMAZON_S3_BASE_URL'].to_s + logo.blob.key if logo.attached?
  end
end

This is the log, they all are similar.

May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1] Started GET "/forest/Deposit/count?fields%5BDeposit%5D=account_id%2Caccount_type%2Camount%2Ccompany_bank_account%2Ccreated_at%2Ccurrency%2Cexpires_at%2Cid%2Cpayment_method_id%2Cpayout_at%2Creceipt_image%2Creceipt_image_attachment%2Creceipt_image_blob%2Creceipt_image_url%2Cstatus%2Ctransaction_type%2Cupdated_at&fields%5Bcompany_bank_account%5D=id&fields%5Breceipt_image_attachment%5D=name&fields%5Breceipt_image_blob%5D=id&timezone=America%2FSao_Paulo" for 172.70.105.135 at 2023-05-24 22:22:25 +0100
May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1] Processing by ForestLiana::UserSpace::DepositController#count as JSON
May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1]   Parameters: {"fields"=>{"Deposit"=>"account_id,account_type,amount,company_bank_account,created_at,currency,expires_at,id,payment_method_id,payout_at,receipt_image,receipt_image_attachment,receipt_image_blob,receipt_image_url,status,transaction_type,updated_at", "company_bank_account"=>"id", "receipt_image_attachment"=>"name", "receipt_image_blob"=>"id"}, "timezone"=>"America/Sao_Paulo", "collection"=>"Deposit"}
May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1]    (0.8ms)  SELECT COUNT(*) FROM "deposits"
May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1] [active_model_serializers] Rendered ActiveModel::Serializer::Null with Hash (0.19ms)
May 24 06:22:25 PM  [c70feefb-8764-4318-b229-fa3425e1d8e1] Completed 200 OK in 5ms (Views: 0.8ms | ActiveRecord: 0.8ms | Allocations: 876)
May 24 06:22:25 PM  [c650d83a-b887-46d6-b773-15046d198e3c] [Rollbar] Success
May 24 06:22:25 PM  [c650d83a-b887-46d6-b773-15046d198e3c] [Rollbar] Details: https://rollbar.com/instance/uuid?uuid=4f3d9098-4fde-490a-a956-26ccebae0e0a (only available if report was successful)
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c]
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] SystemStackError (stack level too deep):
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c]
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activestorage (6.0.5) lib/active_storage/attached/one.rb:13:in `public_send'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activestorage (6.0.5) lib/active_storage/attached/one.rb:13:in `attachment'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/module/delegation.rb:299:in `respond_to_missing?'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:54:in `respond_to?'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:54:in `as_json'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:172:in `block in as_json'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:172:in `each'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:172:in `map'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activesupport (6.0.5) lib/active_support/core_ext/object/json.rb:172:in `as_json'
May 24 06:22:26 PM  [c650d83a-b887-46d6-b773-15046d198e3c] activemodel (6.0.5) lib/active_model/serializers/json.rb:96:in `as_json'

Unfortunately, I am not able to reproduce the problem on my side.

Did you have a specific configuration for has_one_attached?

Can you share the migration of your Bank and Deposit model?

Hi @nicolasa, I haven’t any specific configuration.

Bank Model

class Bank < ApplicationRecord
  has_many :bank_accounts
  has_many :company_bank_accounts
  has_one_attached :logo

  validates :code, presence: true
  validates_format_of :code, with: /\A\d{4}\z/

  scope :list, -> { all.order('name ASC') }

  def aws_logo_url
    ENV['AMAZON_S3_BASE_URL'].to_s + logo.blob.key if logo.attached?
  end
end

Bank Migration

  create_table "banks", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "logo_url"
    t.string "app_link"
    t.string "logo"
    t.string "code"
  end

Thanks.

Hi @nicolasa, thank you for your help.

I was able to find the problem, it was something with Rails to_json method failing to parse the objects.

Thanks.

1 Like