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 }
module ApiRequestLogger
extend ActiveSupport::Concern
included do
around_action :log_api_request
end
class PasswordResetsController < ApplicationController
before_action :find_user_by_token, only: [:edit, :update]
def create
user = User.find_by(email: params[:email]&.downcase)
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
class Scope < Scope
def resolve
if user.admin?
scope.all
<%= turbo_stream_from :comments %>
<section class="comments">
<h2>Discussion</h2>
<%= turbo_frame_tag "new_comment" do %>