Ruby on Rails backend API specialist with 8+ years building scalable REST and GraphQL APIs. Deep expertise in ActiveRecord optimization, background jobs, caching strategies, and...
class PopularPostsQuery
def initialize(relation = Post.all)
@relation = relation
end
def call(timeframe: 7.days, min_views: 100, limit: 20)
class User < ApplicationRecord
has_many :posts, foreign_key: :author_id, dependent: :destroy
before_validation :normalize_email
before_create :generate_auth_token
after_create :send_welcome_email
module Api
module V1
class PostsController < BaseController
before_action :authenticate_user!
def create
class TransferFundsService
def initialize(from_account:, to_account:, amount:)
@from_account = from_account
@to_account = to_account
@amount = amount
end
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins_list = if Rails.env.production?
ENV['CORS_ALLOWED_ORIGINS']&.split(',') || []
else
'localhost:3000', 'localhost:5173', /127\.0\.0\.1:\d+/
class HealthController < ApplicationController
skip_before_action :verify_authenticity_token
def liveness
render json: { status: 'ok' }, status: :ok
end
json.array! @posts do |post|
json.cache! ['v1', post], expires_in: 1.hour do
json.id post.id
json.title post.title
json.excerpt post.excerpt
json.published_at post.published_at
class CreatePostService
def initialize(author:, params:)
@author = author
@params = params
end
class AddIndexesToPosts < ActiveRecord::Migration[6.1]
def change
add_index :posts, :author_id
add_index :posts, :published_at
add_index :posts, [:author_id, :published_at]
add_index :posts, :created_at, order: { created_at: :desc }
class Post < ApplicationRecord
belongs_to :author, class_name: 'User'
has_many :comments, dependent: :destroy
scope :published, -> { where.not(published_at: nil).where('published_at <= ?', Time.current) }
scope :draft, -> { where(published_at: nil) }
:concurrency: 10
:queues:
- [critical, 4]
- [default, 2]
- [low, 1]
Rails.application.configure do
config.after_initialize do
Bullet.enable = true
Bullet.alert = false
Bullet.bullet_logger = true
Bullet.console = true