22 Matching Annotations
  1. Sep 2024
    1. I emphatically disagree with BlueFish about observers being difficult to properly unit test. This is precisely the biggest point that distinguishes them from lifecycle callbacks: you can test observers in isolation, and doing so discourages you from falling into many of the state- and order-heavy design pitfalls BlueFish refers to (which again I think is more often true of lifecycle callbacks).
  2. Jul 2022
    1. ActiveSupport.on_load :active_storage_blob do def accessible_to?(accessor) attachments.includes(:record).any? { |attachment| attachment.accessible_to?(accessor) } || attachments.none? end end ActiveSupport.on_load :active_storage_attachment do def accessible_to?(accessor) record.try(:accessible_to?, accessor) end end ActiveSupport.on_load :action_text_rich_text do def accessible_to?(accessor) record.try(:accessible_to?, accessor) end end module ActiveStorage::Authorize extend ActiveSupport::Concern included do before_action :require_authorization end private def require_authorization head :forbidden unless authorized? end def authorized? @blob.accessible_to?(Current.identity) end end Rails.application.config.to_prepare do ActiveStorage::Blobs::RedirectController.include ActiveStorage::Authorize ActiveStorage::Blobs::ProxyController.include ActiveStorage::Authorize ActiveStorage::Representations::RedirectController.include ActiveStorage::Authorize ActiveStorage::Representations::ProxyController.include ActiveStorage::Authorize end

      Interesting, rather clean approach, I think

  3. Nov 2021
    1. In effect, the $ syntax we've seen above will actually setup a subscription to the store. And the subscription will be cancelled when the component is destroyed. If the store is subscribed by multiple components, the store will be disposed only when the last component unsubscribes (it will be reinitialized, if a new subscription is made). This is very handy to manage the lifecycle of disposable things in your code.
  4. Jun 2021
  5. Mar 2021
  6. Jan 2021
  7. Oct 2020
  8. Sep 2020
  9. Aug 2020
  10. Jul 2020
  11. May 2020