module Book::Accessable extend ActiveSupport::Concern included do has_many :accesses, dependent: :destroy scope :with_everyone_access, -> { where(everyone_access: true) } end class_methods do def accessable_or_published(user: Current.user) if user.present? accessable_or_published_books else published end end def accessable_or_published_books(user: Current.user) user.books.or(published).distinct end end def accessable?(user: Current.user) accesses.exists?(user: user) end def editable?(user: Current.user) access_for(user: user)&.editor? || user&.administrator? end def access_for(user: Current.user) accesses.find_by(user: user) end def update_access(editors:, readers:) editors = Set.new(editors) readers = Set.new(everyone_access? ? User.active.ids : readers) all = editors + readers all_accesses = all.collect { |user_id| { user_id: user_id, level: editors.include?(user_id) ? :editor : :reader } } accesses.upsert_all(all_accesses, unique_by: [ :book_id, :user_id ]) accesses.where.not(user_id: all).delete_all end end