In my Rails 5 application, building a JSON API & using Activestorage for my attachments:
To avoid accessing an attachment that doesn't exist, I am using this if condition as shown in this answer but unfortunately this if condition makes a SQL query to check if the attachment is available or not, causing n+1 queries although I have already included (pre-loaded) the attachments for the records I have
How to check if the attachment exist on a record without hitting the DB, if I have preloaded the attachments already?
I tried to use .nil? but that will give a false positive that there is attachment even if there isn't (as shown below)
ActionView::Template::Error (to_model delegated to attachment, but attachment is nil):
if !product.logo.nil?
json.logo_img url_for(product.logo)
.attached? check works but causes the n+1 queries:
if product.logo.attached?
json.logo_img url_for(product.logo)
So while the below code looks very ugly, it works, preloading the attachments for all the records at once, but when checking if an attachment exists => this leads to n+1 queries
json.array!(@some_records.includes(integrated_product: [company: [ logo_attachment: :blob ]])) do |one_record|
product ||= one_record.integrated_product
if !product.logo.attached?
json.logo_img url_for(product.logo)
elsif !product.company.logo.attached?
json.logo_img url_for(product.company.logo)
end
....
Any thoughts on how to handle this in a proper way (preloading attachments & avoiding n+1) are appreciated.
Update:
I want to have the whole collection that I passed, including items with & without attachment, searching for a condition that will check if that already loaded item has an attachment or not to display an image if it has attachment