<%= form_with model: @document, data: { controller: "upload" } do |form| %>
<div class="field">
<%= form.label :file, "Attach a document" %>
<%= form.file_field :file,
direct_upload: true,
data: { upload_target: "input" } %>
class CreateApiKeys < ActiveRecord::Migration[6.1]
def change
create_table :api_keys do |t|
t.references :user, null: false, foreign_key: true
t.string :name, null: false
t.string :key_digest, null: false
import { createConsumer, Cable } from '@rails/actioncable'
let cable: Cable | null = null
export function getCable(): Cable {
if (!cable) {
Rails.application.config.filter_parameters += [
:password,
:password_confirmation,
:secret,
:token,
:api_key,
class CreateSubscriptions < ActiveRecord::Migration[7.1]
STATUSES = %w[pending active past_due canceled].freeze
def change
create_table :subscriptions do |t|
t.references :account, null: false, foreign_key: true
class Document < ApplicationRecord
belongs_to :account
enum status: { pending: 0, processing: 1, ready: 2, failed: 3 }
after_create_commit :broadcast_badge
class Category < ApplicationRecord
has_many :products, dependent: :restrict_with_error
has_many :subcategories,
class_name: "Category",
foreign_key: :parent_id,
dependent: :restrict_with_error
# Generate engine
# rails plugin new billing --mountable
# lib/billing/engine.rb
module Billing
class Engine < ::Rails::Engine
class RateLimiter
def initialize(key:, limit:, window:)
@key = "rate_limit:#{key}"
@limit = limit
@window = window
end
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["input"]
static values = { wait: { type: Number, default: 300 }, url: String }
.turbo-progress-bar {
height: 4px;
background: linear-gradient(
90deg,
var(--progress-start, #6366f1),
var(--progress-end, #ec4899)
module ApiRequestLogger
extend ActiveSupport::Concern
included do
around_action :log_api_request
end