Skip to content

Instantly share code, notes, and snippets.

View bhserna's full-sized avatar

Benito Serna bhserna

View GitHub Profile

The Unofficial 37signals/DHH Rails Style Guide

About This Document

This style guide was generated by Claude Code through deep analysis of the Fizzy codebase - 37signals' open-source project management tool.

Why Fizzy matters: While 37signals has long advocated for "vanilla Rails" and opinionated software design, their production codebases (Basecamp, HEY, etc.) have historically been closed source. Fizzy changes that. For the first time, developers can study a real 37signals/DHH-style Rails application - not just blog posts and conference talks, but actual production code with all its patterns, trade-offs, and deliberate omissions.

How this was created: Claude Code analyzed the entire codebase - routes, controllers, models, concerns, views, JavaScript, CSS, tests, and configuration. The goal was to extract not just what patterns are used, but why - inferring philosophy from implementation choices.

@bhserna
bhserna / example.rb
Last active May 26, 2025 16:48
A concern to easily add search to a rails model using LIKE (only tested on sqlite)
# You can search on columns of the record or on associations
# Example of a search on the record's column
class Brand < ApplicationRecord
include Searchable
# All this are columns on the Brand record
search_on :id, :name, :description
end
require "tempfile"
xml = '<?xml version="1.0" encoding="UTF-8"?>
<retenciones:Retenciones xmlns:retenciones="http://www.sat.gob.mx/esquemas/retencionpago/1" xmlns:c_retenciones="http://www.sat.gob.mx/esquemas/retencionpago/1/catalogos" xmlns:intereses="http://www.sat.gob.mx/esquemas/retencionpago/1/intereses" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/esquemas/retencionpago/1 http://www.sat.gob.mx/esquemas/retencionpago/1/retencionpagov1.xsd http://www.sat.gob.mx/esquemas/retencionpago/1/intereses http://www.sat.gob.mx/esquemas/retencionpago/1/intereses/intereses.xsd" Version="1.0" FolioInt="5-56-9" FechaExp="2020-06-25T11:58:08-05:00" CveRetenc="16" DescRetenc="0.00" Cert="MIIDhDCCAmygAwIBAgIUMjAwMDEwMDAwMDAzMDAwMjI4MjMwDQYJKoZIhvcNAQEFBQAwSzEVMBMGA1UEAwwMQS5DLiBQcnVlYmFzMRAwDgYDVQQKDAdQcnVlYmFzMQswCQYDVQQGEwJNWDETMBEGA1UEBwwKQ3VhdWh0ZW1vYzAeFw0xNzA0MjgxODMwMzZaFw0yMjEwMTkxODMwMzZaMIGQMRswGQYDVQQDDBJQYWJsbyBOZXJ1ZGEgUGVyZXoxGzAZBgNVBCkMElBhYmxvIE5lcnVkYSB
input = {
"builder_rule_0_filter"=>"artist_name",
"builder_rule_0_operator"=>"contains",
"builder_rule_0_value_0"=>"New Found Glory",
"builder_rule_1_filter"=>"bpm",
"builder_rule_1_operator"=>"less",
"builder_rule_1_value_0"=>"150",
"builder_rule_2_filter"=>"days_ago",
<div class="relative">
<input class="form-control" type="email">
<img class="absolute right-1 top-1" src="#"/>
</div>
@bhserna
bhserna / tic-tac-toe.rb
Created April 12, 2018 23:56
Example of Test contravariance
require "rspec"
module TicTacToe
def self.start_game
Game.new
end
class Game
def initialize
@board = Board.new
class CompaniesController < ApplicationController
STORE = Company
def new
form = CRM.new_company_form
render locals: { form: form }
end
def create
status = CRM.create_company(params[:company], STORE)
@bhserna
bhserna / project.md
Last active August 31, 2017 15:10
Hackfest

Objetivo 1

Construir un programa para compartir los datos de los inversionistas entre plataforma y que sirva como referencia para saber si un usuario ya fue aprobado por alguna otra plataforma.

Registrar usuario

  • Nombre
  • RFC
  • Plataforma que lo registra
# El método :next sirve para decirle a ruby que empieze en ese momento la siguiente iteración.
# En este ejemplo no tiene mucho caso porque si no es impar, ruby como quiera no haría nada. De forma que el siguente ejemplo sería mejor.
(1..20).each do |number|
if number.odd?
puts number
else
next
end
end
@bhserna
bhserna / Carros.rb
Created June 24, 2017 19:09
tarea_clase_3
#-Crear una clase Auto, al instanciar un objeto de la clase dale la oportunidad al usuario de definir variables de instancia como año, color y modelo.También crea una variable de instancia seteada en 0 durante la instanciación del objeto para realizar un seguimiento de la velocidad actual del auto. Crear métodos de instancia que permitan al auto acelerar, frenar, y estacionar (apagar el auto, velocidad 0).
#-Método de instancia de encender el auto, y métodos de obtener la marca y setear una marca.
#-Añadir método accessor a la clase de autos para cambiar y ver el color de su auto. A continuación, añadir otro método accessor que
#le permite ver, pero no modificar, el año de su auto
car = Car.new(2013, :red, "Yaris")
car.brand = "Toyota"
puts car.brand
puts car.color
car.color = :green