Rails + React specialist building modern SPAs with Rails APIs. Expert in React hooks, state management, TypeScript, and seamless Rails integration. 9+ years creating performant,...
class PostsController < ApplicationController
def create
@post = current_user.posts.build(post_params)
if @post.save
flash[:success] = 'Post was successfully created.'
import { useEffect, useState, useRef } from 'react'
interface UseInViewOptions {
threshold?: number | number[]
rootMargin?: string
triggerOnce?: boolean
module Posts
class CreateService
def initialize(author:, params:)
@author = author
@params = params
end
import { useReducer } from 'react'
interface FormState {
values: Record<string, any>
errors: Record<string, string>
touched: Record<string, boolean>
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :posts do
resources :comments, only: [:index, :create]
end
import { useForm } from 'react-hook-form'
import { useState } from 'react'
import api from '@/services/api'
interface SignupFormData {
email: string
class SlugValidator < ActiveModel::Validator
SLUG_REGEX = /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/
def validate(record)
slug = record.send(options[:attribute] || :slug)
Rails.application.config.middleware.insert_before 0, Rack::Cors do
# Development CORS - allow any localhost
allow do
origins(
/http:\/\/localhost:\d+/,
/http:\/\/127\.0\.0\.1:\d+/,
import { memo } from 'react'
import { Post } from '@/types'
interface PostListItemProps {
post: Post
onLike: (id: string) => void
Rails.application.configure do
# Bullet configuration
config.after_initialize do
Bullet.enable = true
Bullet.alert = true # Show JavaScript alert
Bullet.bullet_logger = true # Log to bullet.log
import { useEffect } from 'react'
interface KeyboardHandlers {
[key: string]: () => void
}
FactoryBot.define do
factory :post do
association :author, factory: :user
sequence(:title) { |n| "Post Title #{n}" }
body { Faker::Lorem.paragraphs(number: 3).join("\n\n") }
status { :draft }