I'm using Devise and Active Storage in my rails 6 application. Currently using before_action: authenticate_user!
disables all images for non users, which is great, except I want to allow images with the record_type
'News' in my active_storage_attachments
to be viewable by users and non users.
The below code is what I have so far, looking at ActiveStorage::Attachment where the record_type
is News. This code shows all images for both users and non users which is not ideal.
class ActiveStorage::BaseController < ActionController::Base
before_action :allow_certain_assets
include ActiveStorage::SetCurrent
protect_from_forgery with: :exception
private
def allow_certain_assets
if (ActiveStorage::Attachment.where(record_type: 'News')).present?
else
authenticate_user!
end
end
end
The issue with your code is you are doing this:
(ActiveStorage::Attachment.where(record_type: 'News')).present?
which will check the whole database if there is any attachment
with record_type
'News'. But instead you need to check if the particular image the user is trying to access is of 'News' type then allow him or else don't allow him. One way to do this would be on the show action you can check:
def show
# this code might be incorrect and I am not sure how you would be getting
# the attachment object but this would explain a way you can authenticate it
@attachment = ActiveStorage::Attachment.find params[:id]
authenticate_user! unless @attachment.record_type == 'News'
end
So this will check the particular object the user is trying to access.
Add on:
This type of authorization can be done automatically using some authorization libraries like:
where you can allow certain type of images for guest user too and the other type of images only for a registered user.