module Keysettable
extend ActiveSupport::Concern
included do
scope :keyset_page, ->(after: nil, limit: 20) do
relation = order(created_at: :asc, id: :asc).limit(limit + 1)
module Cacheable
extend ActiveSupport::Concern
def cache_query(prefix, scope, expires_in: 15.minutes)
key = [prefix, cache_version_token(scope)].join("/")
class CreateAuditLogs < ActiveRecord::Migration[7.1]
def change
create_table :audit_logs do |t|
t.references :auditable, polymorphic: true, null: false
t.references :user, null: true, foreign_key: true
t.string :action, null: false
class AddVersionsToArticles < ActiveRecord::Migration[7.1]
def change
add_column :articles, :versions, :jsonb, null: false, default: []
add_index :articles, :versions, using: :gin
end
end
class CreateAuditLogs < ActiveRecord::Migration[7.1]
def change
create_table :audit_logs do |t|
t.references :auditable, polymorphic: true, null: false
t.string :actor
t.string :action, null: false
class DownloadsController < ApplicationController
before_action :authenticate_user!
def show
report = current_account.reports.find(params[:report_id])
authorize! :download, report
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
module Authorizable
extend ActiveSupport::Concern
class NotAuthorized < StandardError; end
included do
module Paginatable
extend ActiveSupport::Concern
Page = Struct.new(:records, :next_cursor, keyword_init: true)
DEFAULT_LIMIT = 25
class AddSoftDeleteToUsers < ActiveRecord::Migration[7.1]
def change
add_column :users, :deleted_at, :datetime
add_index :users, :deleted_at, where: "deleted_at IS NULL", name: "index_users_on_live"
class AddSlugToArticles < ActiveRecord::Migration[7.1]
def change
add_column :articles, :slug, :string
add_index :articles, :slug, unique: true
reversible do |dir|
module HealthCheckable
extend ActiveSupport::Concern
CheckResult = Struct.new(:name, :ok, :message, keyword_init: true)
private