ruby-china/homeland
:circus_tent: An open source forum/community system based on Rails, developed based on Ruby China.
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓6 active contributors
- ✓MIT licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 57% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/ruby-china/homeland)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/ruby-china/homeland on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: ruby-china/homeland
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ruby-china/homeland shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 2d ago
- 6 active contributors
- MIT licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 57% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live ruby-china/homeland
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/ruby-china/homeland.
What it runs against: a local clone of ruby-china/homeland — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in ruby-china/homeland | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ruby-china/homeland. If you don't
# have one yet, run these first:
#
# git clone https://github.com/ruby-china/homeland.git
# cd homeland
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of ruby-china/homeland and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ruby-china/homeland(\\.git)?\\b" \\
&& ok "origin remote is ruby-china/homeland" \\
|| miss "origin remote is not ruby-china/homeland (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "app/controllers/application_controller.rb" \\
&& ok "app/controllers/application_controller.rb" \\
|| miss "missing critical file: app/controllers/application_controller.rb"
test -f "app/models/user.rb" \\
&& ok "app/models/user.rb" \\
|| miss "missing critical file: app/models/user.rb"
test -f "app/models/topic.rb" \\
&& ok "app/models/topic.rb" \\
|| miss "missing critical file: app/models/topic.rb"
test -f "Gemfile" \\
&& ok "Gemfile" \\
|| miss "missing critical file: Gemfile"
test -f "config/routes.rb" \\
&& ok "config/routes.rb" \\
|| miss "missing critical file: config/routes.rb"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ruby-china/homeland"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Homeland is an open-source Rails-based forum and community platform evolved from Ruby China. It provides a full-featured discussion system with topics, replies, nodes, user profiles, and real-time notifications via ActionCable WebSockets, packaged as a deployable Rails monolith with built-in admin panels for moderation and content management. Monolithic Rails app with MVC + components: app/controllers/ holds admin/* and public routes, app/components/ implements ViewComponent-based UI (alert_component, reply_component, topic_component), app/channels/ provides ActionCable WebSockets (notifications_channel, replies_channel), and config/ handles Devise, RuboCop, and deployment. Assets split into SCSS/JS/CSS with Sprockets manifest.
👥Who it's for
Community managers and Ruby developers deploying self-hosted discussion forums or internal knowledge-sharing platforms who want a battle-tested, Rails-native alternative to Discourse without the overhead of a separate container ecosystem.
🌱Maturity & risk
Production-ready and actively maintained. The codebase shows 546KB of Ruby code with established patterns (components, channels, controllers), CI/CD via GitHub Actions (.github/workflows/test.yml, release pipelines), and Docker containerization (.devcontainer, Dockerfile, Dockerfile-base) indicating active deployment infrastructure. Likely 5+ years old given the Ruby China lineage.
Low-to-moderate risk for small communities. Primary concern: single organization maintainer (ruby-china) with unknown issue backlog or PR velocity. Dependency surface is moderate (standard Rails + ActionCable stack evident from directory structure). Monitor the GitHub Actions test.yml workflow frequency and release.yml activity for abandonment signals. No evidence of recent security audits visible in repo structure.
Active areas of work
Active CI/CD pipeline with GitHub Actions: test.yml runs on commits, release.yml and release_tag.yml automate versioning, and release_base.yml manages Docker base image builds. Devcontainer setup (.devcontainer/docker-compose.yml, Dockerfile) suggests recent focus on frictionless local developer setup and Docker-first deployment workflow.
🚀Get running
git clone https://github.com/ruby-china/homeland.git && cd homeland && cp .env.example .env && bundle install && rails db:create db:migrate && ./bin/dev (or make dev from Makefile)
Daily commands: make dev (defined in Makefile, runs Procfile.dev with Foreman), or rails s for just the Rails server. Requires .env configuration; devcontainer provides pre-configured environment via .devcontainer/docker-compose.yml.
🗺️Map of the codebase
app/controllers/application_controller.rb— Core request handler establishing authentication, authorization, and shared behavior for all controllers via concerns in app/controllers/application_controller/app/models/user.rb— Central user domain model supporting Devise authentication, OAuth integration, and team/role relationships that gate all access controlapp/models/topic.rb— Primary content model representing forum discussions; core to search, notifications, and API serializationGemfile— Declares Rails, Devise, Doorkeeper (OAuth2), and plugin architecture dependencies that define the entire runtimeconfig/routes.rb— Maps all HTTP endpoints and namespaces (admin, api/v3, oauth) defining the public and internal contractapp/controllers/api/v3/application_controller.rb— Base API controller establishing token authentication and JSON serialization strategy for all v3 endpoints.github/workflows/test.yml— CI pipeline enforcing test coverage, RuboCop linting, and deployment validation before merge
🛠️How to make changes
Add a new API endpoint
- Create or edit controller in app/controllers/api/v3/{resource}_controller.rb with standard RESTful actions (index, show, create, update, destroy) (
app/controllers/api/v3/topics_controller.rb) - Add route in config/routes.rb under namespace :api do namespace :v3 do resources :{resources} end end (
config/routes.rb) - Add Pundit authorize! call and serialize response using ActiveModel::Serializer in controller actions (
app/controllers/api/v3/application_controller.rb) - Write request spec in spec/requests/api/v3/{resource}_spec.rb covering auth, validation, and edge cases (
spec/requests/api/v3/topics_spec.rb)
Add a new admin feature
- Create controller at app/controllers/admin/{feature}_controller.rb inheriting from Admin::ApplicationController (
app/controllers/admin/nodes_controller.rb) - Add resource to admin namespace in config/routes.rb: namespace :admin do resources :{feature} end (
config/routes.rb) - Create view templates in app/views/admin/{feature}/ using standard ERB or ViewComponent (
app/views/admin/nodes) - Add permission check via admin policy in app/policies/admin/{feature}_policy.rb using Pundit (
app/policies/admin/node_policy.rb)
Add a notification type
- Define notification trigger in relevant model callback (e.g., after_create in Reply model) (
app/models/reply.rb) - Create notification record via Notification.create(user: recipient, action: 'reply_created', notifiable: reply) (
app/models/notification.rb) - Broadcast to subscribers via ActionCable in NotificationsChannel if real-time needed (
app/channels/notifications_channel.rb) - Render in NotificationsController#index or via API in app/controllers/api/v3/notifications_controller.rb (
app/controllers/api/v3/notifications_controller.rb)
🔧Why these technologies
- Rails + ActionCable — Monolithic Ruby web framework with integrated WebSocket support for real-time notifications and live feeds; best for rapid iteration on forum features
- Devise + Doorkeeper — Devise handles user authentication and session management; Doorkeeper provides OAuth2 server for third-party integrations and mobile clients
- Pundit — Fine-grained authorization policies mapping user roles (admin, moderator, user) to resource actions without controller bloat
- ViewComponent — Encapsulates UI logic (topic cards, replies, profile) into reusable, testable components avoiding view spaghetti
- PostgreSQL — Relational database with full-text search and JSONB support for flexible metadata; recommended in Dockerfile
- Docker + Docker Compose — Containerizes Rails app, PostgreSQL, and Redis for reproducible local dev and cloud deployment via Dockerfile
⚖️Trade-offs already made
-
Monolithic Rails app vs. microservices
- Why: Forum is a tightly-coupled domain (topics, replies, notifications) with shared auth; microservices would add operational overhead
- Consequence: Simpler deployment and debugging but limited horizontal scaling of individual features; acceptable for community-size traffic
-
Server-rendered views + Turbo vs. SPA (React/Vue)
- Why: Rails conventions favor server-side rendering; Turbo provides modern UX without JavaScript framework complexity
- Consequence: Faster initial page load and SEO-friendly, but less interactive offline experience; trade-off favors new-user conversions
-
ActionCable for real-time vs. polling
- Why: WebSocket subscriptions reduce server load and provide instant notifications vs. repeated HTTP requests
- Consequence: Requires Redis for cable store in production; connection limits on some shared hosts; improves UX for active forums
-
Plugin architecture (app/plugins) for extensibility
- Why: Allows third parties to add features (integrations, custom moderation) without forking core codebase
- Consequence: Higher maintenance burden on plugin API stability; core team must version and document hooks carefully
🚫Non-goals (don't propose these)
- Does not provide real-time collaborative editing (topic/reply co-authoring)
- Does not include payment/subscription processing (Stripe integration must be added via plugin)
- Does not handle email deliverability (relies on external SMTP or SendGrid
🪤Traps & gotchas
ActionCable requires Redis or in-memory adapter configured in config/cable.yml (not shown but essential for real-time notifications). .env must exist with database credentials, secret_key_base, and RAILS_ENV. Devcontainer assumes Docker daemon; native macOS/Windows Ruby setup may require postgresql-client system dependency. Procfile.dev uses Foreman to coordinate multiple processes (Rails, webpack, etc.); ensure installed or use make dev instead. Admin routes likely require authentication checks in app/controllers/admin/application_controller.rb not shown in snippet.
🏗️Architecture
💡Concepts to learn
- ActionCable WebSockets — Powers real-time notifications and live topic/reply updates in app/channels/; understanding subscription lifecycle and message broadcasting is critical for extending features
- ViewComponent — Replaces ERB partials with Ruby classes in app/components/; enforces encapsulation and testability, becoming Rails standard for complex UIs
- Devise Authentication — Implicit in controller structure; provides user sign-up, sign-in, and session management that gates forum and admin access
- Server-Sent Events (SSE) vs WebSockets — ActionCable uses WebSockets for bidirectional real-time; understanding when to use SSE (simpler, one-way) vs WebSockets informs feature design
- Rails Database Migrations — db/migrate/ (not listed but inferred) defines schema versioning for topics, replies, users, nodes; essential for understanding data model and deployment consistency
- Docker Multi-Stage Builds — Dockerfile and Dockerfile-base split layers for caching and size optimization; critical for deploying to Kubernetes or container registries without bloat
- RuboCop Linting & Style Enforcement — .rubocop.yml and .autocorrectignore enforce code style consistency across 546KB of Ruby; understanding rules avoids PR rejection cycles
🔗Related repos
discourse/discourse— Industry-standard open-source forum; direct competitor with larger feature set and Ember.js frontend, but heavier deployment footprintruby-china/ruby-china— Predecessor/sister project; Homeland was forked and refactored from this for community reuse, shares domain knowledgeforem/forem— Rails-based community platform (powers DEV Community); similar architecture, comparable real-time and moderation featuresmastodon/mastodon— Rails + ActivityPub federation; complementary for building federated social networks on top of Homeland-like discussion coresrails/rails— Core dependency; understanding ActionCable WebSocket implementation and ViewComponent patterns requires Rails internals knowledge
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive tests for API v3 controllers
The API v3 controllers (app/controllers/api/v3/*.rb) lack visible test coverage. Given this is a public API used by mobile clients (evidenced by app/channels/devices_controller.rb and device management), adding controller specs would ensure API reliability, validate request/response contracts, and prevent regressions. This is critical for a forum system where API stability affects third-party integrations.
- [ ] Create spec/controllers/api/v3/topics_controller_spec.rb with tests for CRUD operations and authorization
- [ ] Create spec/controllers/api/v3/replies_controller_spec.rb for reply listing and creation
- [ ] Create spec/controllers/api/v3/users_controller_spec.rb for user profile and authentication endpoints
- [ ] Create spec/controllers/api/v3/notifications_controller_spec.rb for notification fetching
- [ ] Create spec/controllers/api/v3/likes_controller_spec.rb for like creation/deletion
- [ ] Add shared examples for pagination, error handling, and authentication across all API specs
Add component integration tests for ViewComponents
The app/components directory contains 6 ViewComponents (alert, profile_card, reply, reply_to, topic, application) but no visible spec files. Since these are reusable UI elements displayed across the forum, adding component specs would ensure rendering consistency, validate slot usage, and catch view-level bugs. This is especially important for topic_component.rb and reply_component.rb which are likely used heavily.
- [ ] Create spec/components/topic_component_spec.rb to test topic rendering with various states (locked, pinned, deleted user, etc.)
- [ ] Create spec/components/reply_component_spec.rb to test reply rendering and reply_to nesting
- [ ] Create spec/components/profile_card_component_spec.rb to test user card display with different user attributes
- [ ] Create spec/components/alert_component_spec.rb to test alert variants (success, error, warning)
- [ ] Add shared component test helpers in spec/support/component_helpers.rb for consistent testing patterns
Create ActionCable channel integration tests
The app/channels directory defines notifications_channel.rb and replies_channel.rb for real-time updates, but lacks visible test coverage. These WebSocket channels are critical for user experience (live notifications, comment threads). Adding channel tests would validate subscription logic, message broadcasting, and authorization to prevent real-time feature regressions.
- [ ] Create spec/channels/notifications_channel_spec.rb to test subscription authorization and message broadcasting for different user types
- [ ] Create spec/channels/replies_channel_spec.rb to test topic-specific reply subscriptions and broadcast filtering
- [ ] Create spec/channels/application_cable/connection_spec.rb to test WebSocket connection authentication using current_user
- [ ] Add shared channel test helpers in spec/support/channel_helpers.rb for subscription and broadcast assertions
- [ ] Document channel subscription flow in CONTRIBUTE.md with examples
🌿Good first issues
- Add unit tests for app/components/reply_component.rb and reply_to_component.rb (ViewComponent tests are minimal risk, high value for newcomers)
- Document the admin controller structure and permission model in CONTRIBUTE.md; current file list shows 10+ admin/* controllers but no visible permission pattern or audit trail
- Implement missing enum or scope helpers for Topic.status or Reply.state in models/ (implied by topic_component, not shown in structure; standardizes query patterns)
⭐Top contributors
Click to expand
Top contributors
- @huacnlee — 57 commits
- @Eric-Guo — 28 commits
- @qichunren — 9 commits
- @dependabot[bot] — 3 commits
- @gith-u-b — 2 commits
📝Recent commits
Click to expand
Recent commits
9f5dbde— Bump rack from 3.2.1 to 3.2.2 (#1479) (dependabot[bot])cf7da5c— Bump Shakapacker to v8.4.0 (#1477) (Eric-Guo)a823558— Fix migration error by use sql execute. (huacnlee)3cc638f— Enable confirmable for Devise. (#1470) (huacnlee)7e56045— Fix admin interface User state can't save. (#1458) (huacnlee)cfbab65— Install ImageMagick to fix CI (#1450) (huacnlee)a204b3c— Update CI to use Ruby 3.4 (huacnlee)f2a6c17— Update Docker iamge to use Ruby 3.4 (huacnlee)616ec5d— Bump rails-html-sanitizer from 1.6.0 to 1.6.1 (#1448) (dependabot[bot])df4706c— Add devcontainer (#1446) (chloerei)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.