Wiki › Tier 1
Ruby & Rails
Ruby & Rails
Welcome to the Ruby & Rails wiki page. This page provides an overview of the Ruby programming language, its most prominent web framework, Ruby on Rails, and guidelines for developer training and development practices. It also covers how to integrate JavaScript behavior using Stimulus, explores Ruby's emerging role in AI development, delves into architectural patterns like Delegated Types, examines modern approaches to the Rails view layer, and introduces real-time communication with Action Cable. Additionally, it touches upon game development with Ruby and crucial considerations for upgrading Rails applications.
Overview of Ruby
Ruby is a powerful, object-oriented programming language. Designed for versatility, it runs on *nix systems and serves as an effective backend language for various web architectures (such as Sinatra-based backend applications).
The Ruby on Rails Framework
While Ruby is a highly capable language on its own, it is most closely associated with its most famous framework, Ruby on Rails (often simply referred to as Rails).
- Maturity & Security: Rails is a mature framework designed for building secure web applications.
- Documentation: The framework is well-supported and officially documented.
- Active Ecosystem: Rails and other Ruby gems (software packages) are updated frequently to ensure security and stability.
Key Benefits & Capabilities
- Rapid & Iterative Development: Combining the Ruby language with the Rails framework enables highly rapid and iterative development cycles.
- Extensibility: For performance or system-level enhancements, developers can write Rust code directly within a Ruby on Rails application.
Startups on Rails: Success Stories and Best Practices
The success of numerous startups is a testament to the power and scalability of Ruby on Rails. Platforms like Uscreen, which bootstrapped for 10 years before a significant funding round, demonstrate how Rails can fuel lean growth and facilitate the creation of massive platforms.
Uscreen Case Study
Nick Savrov, Co-founder & CTO of Uscreen, shared insights into their journey:
- Bootstrapping for Growth: Uscreen successfully operated for a decade, focusing on lean development and iterating rapidly with Rails before strategically raising $150 million. This highlights Rails' capability to support sustained growth without immediate external investment.
- Rails for Fast Iteration: The framework's conventions and developer productivity features were instrumental in Uscreen's ability to pivot and adapt, ultimately powering a creator payout platform valued at nearly $1 billion.
- Keeping the Tech Stack Simple: A core principle for Uscreen's scaling was maintaining a simple tech stack, underscoring the importance of judicious technology choices for long-term success.
- Mobile Apps with Rails: Early adoption of technologies like Turbolinks allowed Rails to effectively power mobile applications, showcasing its versatility.
Gusto: A Multi-Billion Dollar Rails Monolith
Edward Kim, co-founder and CTO of Gusto, shared insights into building their HR and payroll software, which has grown from a Y Combinator startup into a multi-billion dollar company, largely powered by a Rails monolith with 10 million lines of code.
- Early Adoption and Rapid Development: Kim was drawn to Rails early on by DHH's screen share video demonstrating the rapid creation of a blog application. This initial exposure highlighted Rails' potential for building complex features quickly, a capability that proved foundational for Gusto.
- Scalability of the Monolith: Gusto's success demonstrates that a well-managed Rails monolith can scale effectively to support a large and growing user base and code base.
- Community Support: Gusto is a significant supporter of the Ruby and Rails community, sponsoring conferences and events, underscoring the importance of a vibrant ecosystem for sustained growth.
This case study reinforces that Rails remains a potent choice for startups aiming for significant scale and market impact.
RubyConfTH 2026: Startups on Rails in 2026
Irina Nazarova's keynote at RubyConfTH 2026 provided insights into the current landscape of startups leveraging Ruby on Rails. Key observations from her talk include:
- Addressing the "Are You Still Using Ruby?" Question: Nazarova acknowledged the prevalent sentiment of doubt surrounding Ruby and Rails, often voiced by those who have moved away from the framework. Her investigation involved over 50 interviews with founders who chose Ruby/Rails recently, alongside practical experience from working with 25 Rails startups at Evil Martians.
- The "Fear Factor": A significant theme identified was "fear." This fear stems not only from the perceived threat of AI taking jobs but also from the dominance of Python in the AI space, leading to anxiety about Ruby's relevance.
- Ruby's Enduring Strengths: Despite anxieties, Nazarova's research indicates that Ruby and Rails continue to be viable and productive choices for startups. The underlying message suggests that the "fear" might be more about perception than a fundamental decline in the framework's capabilities for building successful businesses.
Nazarova's talk aims to counter anxieties by highlighting the continued adoption and success of Ruby and Rails in the startup ecosystem, emphasizing that the framework remains a powerful tool for innovation and business growth.
Game Development with Ruby
While Ruby on Rails is primarily known for web development, the Ruby language itself is capable of game development, often overlooked by developers drawn into other ecosystems.
Ruby's GameDev Potential
- Familiar Syntax: Developers already proficient in Ruby can leverage their existing knowledge to build games without learning entirely new languages or complex engines.
- "Scratch That Itch": Projects and talks like Matheus Richard's aim to demonstrate that building games is achievable with Ruby, addressing the common developer aspiration to create games that often gets sidelined by professional commitments.
- Leveraging Existing Tools: While specific game development libraries and frameworks might be less prominent than in other languages, Ruby's flexibility allows for creative solutions and the development of custom tools.
The message is that the barrier to entry for game development can be significantly lowered for Rubyists, empowering them to pursue their gamedev passions with the language they already know.
Integrating JavaScript with Stimulus
Stimulus is a JavaScript framework designed to enhance existing HTML, not replace it. In a Rails application, the server renders the HTML first, and Stimulus then attaches small pieces of behavior to that HTML via data-* attributes.
Mental Model: HTML Calls JavaScript
Unlike frameworks where JavaScript renders HTML, Stimulus operates on the principle that server-rendered HTML is the source of truth, and JavaScript adds behavior to it.
- React: JavaScript renders HTML.
- Stimulus: HTML calls JavaScript.
Stimulus is DOM-oriented and does not attempt to "own" the DOM, differentiating it from frameworks like React.
Usage in Rails Views
Rails views opt into Stimulus using the data-controller attribute. Multiple controllers can be attached to a single element.
Example:
<%= form_with model: @report_provider,
method: :put,
data: {
controller: "dirty-state verify-section",
action: "change->dirty-state#markDirty input->dirty-state#markDirty submit->dirty-state#reset"
} do |form| %>
...
<% end %>
This renders to HTML as:
<form
data-controller="dirty-state verify-section"
data-action="change->dirty-state#markDirty input->dirty-state#markDirty submit->dirty-state#reset">
...
</form>
Stimulus scans the DOM, identifies the data-controller attributes, and instantiates the corresponding JavaScript controller classes (e.g., app/javascript/controllers/dirty_state_controller.js for data-controller="dirty-state").
Actions
The data-action attribute connects DOM events to specific controller methods.
Example:
data: { action: "click->dirty-state#interceptNav" }
This configuration means: "When this element is clicked, call the interceptNav() method on the dirty-state controller."
Controller Method Example:
interceptNav(event) {
if (!this.isDirty) return;
event.preventDefault();
this.pendingHref = event.currentTarget.href;
this.unsavedModalTarget.querySelector('dialog').showModal();
}
Targets
Targets provide named references to important DOM elements within a controller, simplifying interaction with specific parts of the HTML.
In the View:
<%= form.hidden_field :is_verified_section,
value: '',
data: { 'verify-section-target': 'flag' } %>
In the Controller:
export default class extends Controller {
static targets = ['flag', 'confirmBtn'];
confirm() {
this.flagTarget.value = '1';
this.element.requestSubmit();
}
}
The data-verify-section-target="flag" attribute in the HTML makes this.flagTarget available within the controller.
Stimulus vs. jQuery
Stimulus shares a philosophical alignment with jQuery in its approach to enhancing HTML with JavaScript behavior.
Training and Skill Acquisition
To train developers—including senior developers—effectively in this ecosystem, a structured approach is recommended:
- Establish a Foundation in Ruby First: A solid foundation in Ruby is highly beneficial for developers. Ruby on Rails should only be introduced after a trainee has acquired a strong understanding of the core Ruby language.
- Deepen Skills with Specific Resources: Utilizing specific, recommended training materials is advised to further deepen both Ruby and Rails capabilities.
- Learn Stimulus for Frontend Interactivity: Understanding Stimulus is crucial for adding dynamic behavior to server-rendered HTML within Rails applications.
Ruby 4.0 Upgrade Considerations
Upgrading Ruby versions, particularly to major releases like 4.0, can introduce subtle changes that impact application behavior. A recent upgrade to Ruby 4.0.1 highlighted several such issues, particularly affecting the bin/dev startup process. These issues often manifest as a chain of dependencies, where fixing one bug reveals the next.
Common Upgrade Pitfalls and Fixes
When upgrading Ruby, pay close attention to:
- Constant Lookup Rules: Newer Ruby versions may enforce stricter rules for constant lookup. For instance, a constant implicitly referenced within a class body might no longer resolve to its expected outer scope, requiring explicit qualification (e.g.,
SolidQueue::Configurationinstead of justConfiguration).- Symptom:
NameErrorfor core framework components during startup. - Fix: Qualify constants explicitly or, if a CLI is broken, invoke core methods directly.
- Symptom:
- Gem ABI Compatibility: Precompiled binaries for gems are often tied to specific Ruby Application Binary Interfaces (ABIs). Upgrading Ruby can invalidate these binaries, leading to segfaults.
- Symptom:
segfaulterrors, especially in gem-heavy applications. - Fix: Force compilation from source for problematic gems (e.g.,
force_ruby_platform: trueinGemfile).
- Symptom:
- Bundler Behavior: Newer Bundler versions might be stricter about executing gems not explicitly declared in the
Gemfile, even if they are dependencies of other development tools.- Symptom: Development tools like
foremanfailing to start. - Fix: Explicitly add the necessary gem to the
Gemfilein the appropriate group (e.g.,:development).
- Symptom: Development tools like
- Process Management and TTYs: Development tools that rely on standard input for interactive commands (like
tailwindcss -w) might behave differently when run under process managers likeforeman, which may not provide a TTY.- Symptom: Watch processes exiting immediately.
- Fix: Use alternative command flags or configurations that don't rely on TTY input (e.g.,
tailwindcss:watch[always]).
- Fork-Safety of Libraries: Libraries that perform system-level operations or manage connections may not be fork-safe. When application workers fork, these libraries can crash.
- Symptom: Segfaults in specific library functions when workers are forked.
- Fix: Reconfigure the library to run in an alternative mode, such as async mode using threads instead of forks, for local development.
Diagnostic Strategy
When facing cascading startup failures:
- Verify Environment: Ensure the correct Ruby version is active and the
bundleis installed correctly. - Isolate Code Paths: Run critical startup components in isolation using
bundle exec ruby -e "..."to pinpoint the first failing piece of code. - Systematic Debugging: Address each
NameErroror crash as it appears. Fixing one issue will often reveal the next in the sequence. - Consult Documentation: Refer to the release notes for Ruby and involved gems for any breaking changes or known issues related to newer versions.
Ruby's Role in AI Development: A New Frontier
The landscape of Artificial Intelligence development is shifting. While Python has traditionally dominated model training due to its extensive libraries and ecosystem, the increasing size and cost of modern AI models mean that training is becoming less accessible to individual developers. The focus is consequently moving towards building AI-powered products, which involves integrating existing models through APIs.
This shift presents a significant opportunity for Ruby. As Carmine Paolino highlights, when the challenge is product development rather than model training, simplicity becomes paramount. Ruby, and by extension Ruby on Rails, is exceptionally well-suited for this task.
RubyLLM and the "One API" Philosophy
Projects like RubyLLM exemplify this new direction. The core idea is to provide a unified API layer that can interact with various AI models and vendors. This allows a single developer, working on a single machine, to build sophisticated AI applications.
- Simplicity as a Competitive Advantage: While Python developers may be engrossed in debugging complex frameworks, Ruby developers can leverage their existing expertise and the Rails ecosystem to rapidly build and deploy AI-powered features.
- Rails for AI Product Development: Ruby on Rails, with its convention-over-configuration principles and strong emphasis on developer productivity, is an ideal framework for rapidly assembling AI products. It enables developers to focus on business logic and user experience rather than low-level AI infrastructure.
Carmine Paolino's keynote at the San Francisco Ruby Conference 2025 articulates this vision: "One API for every model, every vendor. One developer on one machine serving thousands. While Python developers debug their 14-line ‘Hello World,’ we’re shipping. Ruby’s time in AI isn’t coming. It’s here."
This signifies a powerful resurgence for Ruby and Rails, positioning them as key players in the next wave of AI product innovation.
RubyConfTH 2026 - Carmine Paolino - Keynote: Ruby Is the Best Language for Building AI Web Apps
Carmine Paolino's keynote at RubyConfTH 2026 emphasized Ruby's suitability for building AI web applications, particularly in the current landscape where product development and integration are prioritized over model training.
Key Takeaways:
- Shifting AI Development Landscape: The massive cost of training modern AI models means the focus is moving from model training to building AI-powered products by integrating existing models via APIs.
- Ruby's Simplicity Advantage: In this new paradigm, simplicity becomes a key differentiator. Ruby excels at rapid product development.
- RubyLLM as an Example: Projects like RubyLLM demonstrate how a unified API layer can simplify interaction with various AI models and vendors, enabling developers to build sophisticated AI applications on a single machine.
- Rails for AI Products: Ruby on Rails, with its focus on developer productivity and convention over configuration, is an ideal framework for quickly assembling and deploying AI-powered features.
Paolino contrasts this with the Python ecosystem, suggesting that while Python developers might be bogged down in complex framework debugging, Ruby developers can leverage their existing skills to ship AI products faster. The core message is that "Ruby's time in AI isn’t coming. It’s here." This positions Ruby and Rails as strong contenders in the next phase of AI innovation.
The Rails Delegated Type Pattern
The Delegated Type pattern in Rails, championed by 37signals and discussed by Jeffrey Hardy, offers a robust approach to managing polymorphic associations and diverse content types within a single application. This pattern is crucial for scaling complex products like Basecamp and HEY.
Core Concepts: "Recordables"
The pattern often refers to "recordables" – essentially, different types of content that share common attributes but have unique behaviors. Examples include messages, comments, or other content units within an application.
- "Dumb" Recordables: The core "recordable" objects are designed to be simple, holding only essential data (e.g., title and content for a message). They have minimal connection to the outside world, making them highly adaptable. This architectural choice allows for rapid development of new features that interact with these recordables, often achievable in weeks rather than months. The pattern has proven its worth, enabling the 37signals team to scale applications like Basecamp for over a decade without constant rewrites.
Delegated Type Hierarchy
Delegated Types provide a structured way to handle polymorphism, offering an alternative to Single-Table Inheritance (STI) which can become unwieldy.
- Challenge with Single-Table Inheritance (STI): STI can lead to large tables with many NULL columns and can make querying and organizing different content types difficult as the system scales.
- Delegated Types Solution: This pattern allows for a cleaner separation of concerns. A central "recordable" model can delegate its behavior and attributes to specific subtype models, leading to a more organized and maintainable structure.
Organizing Content and History
The Delegated Type pattern simplifies several key aspects of complex application development:
- Copying and Moving Content: The modular nature of recordables makes operations like copying or moving content across different types or locations much more manageable.
- Tracking Change History: By associating events with recordables, it's easier to build comprehensive version history and timelines for content.
- Pagination and Querying: Efficiently querying and paginating across various content types becomes more straightforward due to the structured organization.
Tradeoffs and Learning Curve
While highly beneficial for long-term scalability and faster feature development, the Delegated Type pattern does have a learning curve. Understanding the relationships between the delegated types and how to manage them effectively is key to leveraging its full potential.
Documentation
Evolving the Rails View Layer: Herb and ReActionView
The evolution of web development frameworks constantly pushes for improved developer experience and maintainability. Marco Roth's work on Herb and ReActionView represents a significant step forward in modernizing the Rails view layer, aiming to provide a more robust and ergonomic foundation for building web applications.
Herb: A Modern HTML/ERB Ecosystem
Herb is an open-source project designed to improve the developer experience around HTML and ERB (Embedded RuBy) templating in Ruby web frameworks. It aims to provide a more structured and predictable way to work with view code.
- Goals: Herb seeks to address the complexities and potential pitfalls of traditional ERB by offering enhanced tooling and a more opinionated approach to template management. This includes better support for features like components and improved error handling during development.
- Developer Ergonomics: By providing a more cohesive ecosystem, Herb aims to make writing and maintaining view logic in Rails more productive and enjoyable.
ReActionView: Integrating Modern View Patterns
ReActionView is built upon Herb and is intended to integrate these improvements directly into the Rails framework, acting as a new foundation for its view layer.
- Foundation for View Layer: This project aims to offer a contemporary approach to handling server-rendered HTML within Rails, potentially incorporating concepts from modern JavaScript front-end patterns while retaining the benefits of server-side rendering.
- Beyond Hotwire: While Hotwire (Stimulus, Turbo) has already revolutionized how Rails handles dynamic interfaces, ReActionView seems to explore deeper architectural changes for the view layer itself, potentially offering a more integrated and powerful solution for complex UI needs.
- Leveraging Open Source: Marco Roth's involvement in projects like Stimulus Reflex and Turbo, alongside his maintenance of Stimulus, indicates a deep understanding of the current Hotwire ecosystem and a desire to build upon it with ReActionView.
The development of Herb and ReActionView suggests a continued commitment to innovation within the Ruby and Rails community, focusing on making the view layer more powerful, maintainable, and developer-friendly.
RubyConfTH 2026 - Marco Roth - Keynote: Herb to ReActionView: A New Foundation for the View Layer
Marco Roth's keynote at RubyConfTH 2026, "Herb to ReActionView: A New Foundation for the View Layer," presented his work on open-source projects aiming to modernize the view layer in Rails and other Ruby web frameworks.
Key Takeaways:
- Modernizing the View Layer: Roth introduced Herb, an ecosystem aimed at improving the developer experience with HTML and ERB, and ReActionView, which integrates these advancements into Rails to provide a new foundation for its view layer.
- Developer Productivity: The core motivation behind these projects is to keep Ruby attractive and productive for developers. By enhancing tooling and providing more structured approaches, Roth aims to make writing and maintaining view code more efficient.
- Evolution Beyond Hotwire: While acknowledging the impact of Hotwire (Stimulus, Turbo), ReActionView appears to be exploring deeper architectural improvements for the Rails view layer, potentially incorporating modern front-end concepts while preserving server-side rendering benefits.
- Open Source Contributions: Roth's experience with projects like Stimulus Reflex and Turbo, and his maintenance of Stimulus, underscore his commitment to the evolving Rails landscape and his drive to innovate within the ecosystem.
This initiative signals a proactive effort within the Ruby community to adapt to new development paradigms and enhance the core functionalities of frameworks like Rails, ensuring their continued relevance and appeal.
Real-time Communication with Action Cable (Rails 5+)
Action Cable is a framework integrated into Rails 5+ that enables real-time, bidirectional communication between clients and servers using WebSockets. It allows developers to build features that require instant updates without constant polling.
Core Concepts:
- WebSockets: Action Cable leverages WebSockets to maintain persistent connections between the browser and the server. This is a departure from the traditional HTTP request-response cycle.
- Channels: Actions are organized around channels. A channel is a named broadcast endpoint that clients can subscribe to. For example, a chat application might have a
#chat_roomchannel. - Server-Side Connections: Rails handles the WebSocket connection management on the server. This requires a multi-threaded server like Puma, as each open connection consumes resources.
- Client-Side JavaScript: JavaScript in the browser connects to the Action Cable server and subscribes to channels.
Setup and Configuration:
- Server Requirements: Action Cable requires a WebSocket server capable of handling many concurrent connections. Puma is a recommended choice.
- Dual Server Execution: Typically, you will run two servers:
- The regular Rails application server (e.g.,
bin/rails server). - The Action Cable server (e.g.,
bin/cable server).
- The regular Rails application server (e.g.,
- Redis: Action Cable uses Redis as a message broker to broadcast messages between server processes and to clients across different connections.
Usage Example:
When a user visits a page that uses Action Cable (e.g., sessions/new in an example), they establish a connection. Multiple clients can connect to the same channel to receive real-time updates.
# Example: app/channels/chat_channel.rb
class ChatChannel < ApplicationCable::Channel
def subscribed
stream_from "chat_room_#{params[:room_id]}"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
def receive(data)
# Process messages received from clients
ActionCable.server.broadcast("chat_room_#{params[:room_id]}", { message: data['message'] })
end
end
// Example: app/javascript/channels/chat_channel.js
import consumer from "../channels/consumer"
consumer.subscriptions.create({ channel: "ChatChannel", room_id: 1 }, {
connected() {
// Called when the subscription is ready for use on the server
console.log("Connected to chat channel!");
},
disconnected() {
// Called when the subscription has been interrupted
},
received(data) {
// Called when there's incoming data on the websocket for this channel
console.log("Received data: ", data);
// Update UI to display the new message
},
speak(message) {
return this.perform('receive', { message: message });
}
});
Benefits:
- Real-time Features: Enables features like live chat, notifications, collaborative editing, and live data feeds.
- Rails Integration: Seamless integration within the Rails ecosystem, leveraging familiar patterns and conventions.
- Scalability: Designed to handle a large number of concurrent connections with the right server configuration.
Ruby's Future in AI Development: Matz's Vision
Yukihiro Matsumoto (“Matz”), the creator of Ruby, shared his insights on the future of programming languages in the age of AI during his keynote at Baltic Ruby 2025. Matz discussed the characteristics of languages ideal for AI challenges and Ruby's potential role in this evolving landscape.
Key Considerations for AI-Ready Languages:
Matz emphasized that while Python has been the go-to for AI model training, the increasing complexity and cost of training are shifting the focus towards AI product development. This paradigm shift highlights the value of languages that excel in:
- Simplicity and Developer Productivity: As AI integration becomes more about building user-facing applications rather than raw model training, the ease of development and the ability to iterate quickly become critical. Ruby's long-standing strengths in these areas are seen as a significant advantage.
- Expressiveness and Readability: A language that allows developers to express complex ideas clearly and concisely is crucial for building and maintaining sophisticated AI-powered applications.
- Robust Ecosystems for Integration: While specialized AI libraries are essential for training, the ability to easily integrate with existing services and APIs is paramount for product development. Ruby's mature gem ecosystem and the Rails framework provide a strong foundation for this.
Ruby's Potential in the AI Age:
Matz's perspective suggests that Ruby is well-positioned to thrive in the AI era, particularly in the domain of building AI-powered products. This aligns with the sentiments expressed by Carmine Paolino regarding Ruby's role in AI product development, emphasizing simplicity as a competitive advantage.
- Leveraging Existing Strengths: Ruby's object-oriented nature, its focus on developer happiness, and the powerful conventions of Rails make it an attractive choice for developers who want to build AI applications without getting bogged down in low-level AI infrastructure complexities.
- Focus on "AI-Powered Products": As the industry moves from solely training models to integrating them into user-friendly applications, languages that simplify the development process will gain prominence. Ruby, with its proven track record in web development, is poised to be a major player in this transition.
Matz's insights provide a forward-looking perspective on how Ruby can continue to be a relevant and powerful language in the rapidly evolving field of Artificial Intelligence.
Making Rails AI-Ready by Design with the Model Context Protocol (MCP)
The rapid advancement of Large Language Models (LLMs) presents a significant opportunity to bridge the gap between traditional web applications and AI-powered solutions. The Model Context Protocol (MCP), an emerging standard backed by major players like Google and OpenAI, aims to simplify the interaction between LLMs and server-side applications. This protocol is key to making Rails applications "AI-ready by design," enabling features like AI-driven booking confirmations and personalized user experiences.
The Challenge: Bridging the Gap Between LLMs and Applications
LLMs, while powerful, lack direct access to real-world data and the state of classical applications. A prompt asking an LLM to book a trip, for instance, would fail without a mechanism to connect the LLM's reasoning to the application's booking system. MCP addresses this by providing a standardized way for LLMs to interact with application data and functionality.
Model Context Protocol (MCP) Explained
MCP acts as an intermediary, allowing LLMs to:
- Access Application Data: LLMs can query and understand the context of your application's data (e.g., available hotels, user preferences, booking status).
- Execute Application Actions: LLMs can trigger specific actions within your application (e.g., book a hotel, send a confirmation email, update user profiles).
This opens up possibilities for:
- Natural Language Interfaces: Users can interact with your Rails application using natural language prompts through their preferred LLM interfaces (e.g., ChatGPT, cloud AI, desktop assistants).
- Automated Workflows: Complex tasks can be automated by an LLM that can interpret user intent and interact with the application's backend.
- Personalized Experiences: AI can leverage user data to provide highly tailored recommendations and services.
Rails' Competitive Advantage in the AI Era
Paweł Strzałkowski's presentation at Rails World highlights how Rails' core principles, particularly "convention over configuration," position it favorably for AI integration through MCP:
- Simplicity and Convention: Rails' established conventions make it easier to implement the structured interactions required by MCP. The framework's focus on developer productivity allows for rapid integration of AI capabilities.
- Rapid Development: Just as Rails scaffolds can quickly generate web interfaces, MCP, combined with Rails, can simplify the creation of AI-driven features. This allows developers to focus on delivering AI-powered products rather than getting bogged down in complex integration logic.
- Developer Experience: By embracing MCP, Rails developers can leverage their existing skills to build sophisticated AI applications, similar to how DHH's early demos showcased the ease of building web interfaces.
Implementation and Future
The adoption of MCP suggests a future where Rails applications can seamlessly integrate with AI, offering enhanced user experiences and powerful automated functionalities. This positions Ruby on Rails as a strong contender in the AI-powered application development landscape.
Diagnosing Resource Deletion/Missing Issues in Rails
When resources are unexpectedly missing from an index view, the most common culprit is the filter_by_user scope applied to the Resource model. This scope is designed to filter resources based on the user's role and associated audiences.
The filter_by_user Scope
The Resource.filter_by_user(user_id) scope restricts visibility based on the user's role:
- Provider users: See resources with
audienceof:all_audiencesor:providers. - SPC users: See resources with
audienceof:all_audiencesor:states. - Admin, SAMHSA, TA users: See resources with
audienceof:all_audiences,:providers, or:states.
If a resource's audience attribute does not align with the current user's role, it will exist in the database but will not appear in the filtered list.
# app/models/resource.rb
scope :filter_by_user, -> (user_id) do
u = User.find(user_id)
audience = [:all_audiences]
if u.provider?
audience << :providers
elsif u.spc?
audience << :states
elsif u.admin? || u.samhsa? || u.ta?
audience << :providers
audience << :states
end
where(audience: audience)
end
Other Potential Causes for Missing Resources
- Validation Failures: Resources must pass strict validations to be saved or updated. Common issues include:
- Incorrect
filevs.urlpresence (must have one, not both, not neither). - Invalid URL format (especially with recent validation additions).
- Missing
title. -
descriptionexceeding the 390-character limit. Failed validations can prevent resources from being saved or updated correctly.
- Incorrect
- URL Validation Issues: Edge cases in the new
url_formatvalidation might incorrectly reject valid URLs. - ActiveStorage File Issues: If a resource's attached file is purged from ActiveStorage and the resource lacks a
url, it might become invalid. - Database Constraints: Unexpected database-level constraints could also interfere with resource saving.
Diagnostic Steps
To diagnose missing resources:
Verify Filtering:
Rails Console:
```rubyCheck total resource count
Resource.count
Inspect all resources and their audiences
Resource.all.map { |r| [r.id, r.title, r.audience] }
Check resources visible to a specific user
user = User.find(YOURUSERID)
Resource.filterbyuser(user.id).map { |r| [r.id, r.title, r.audience] }Compare counts and content to identify filtered resources
Check for Validation Errors:
- Rails Console:
ruby Resource.all.each do |r| unless r.valid? puts "Resource #{r.id} (#{r.title}) is invalid: #{r.errors.full_messages}" end end
- Rails Console:
Inspect Database Directly:
SQL:
```sql
-- Check all resources in the database
SELECT id, title, audience, resourcetype, createdat, updatedat
FROM resources
ORDER BY createdat DESC;-- Check for presence of URLs and attached files
SELECT id, title,
CASE WHEN url IS NOT NULL AND url != '' THEN 'hasurl' ELSE 'nourl' END as urlstatus,
(SELECT COUNT(*) FROM activestorageattachments
WHERE recordtype = 'Resource' AND recordid = resources.id) as filecount
FROM resources;
```
Solutions
If the issue is confirmed to be the filter_by_user scope:
- Adjust Resource Audiences: Ensure resources are assigned the correct
audienceattribute that matches the roles of users who should see them.
Building Reliable Agent Skills: Evals are Essential
In the rapidly evolving world of AI agents and their associated "skills" (i.e., specialized functions or tools that agents can call), a critical gap exists: the lack of robust evaluation for these skills before deployment. Philipp Schmid of Google DeepMind highlights that while many skills are developed, very few undergo rigorous testing. This is analogous to shipping code without tests – it significantly increases the risk of failures in production, leading to poor user experiences.
The Problem: "Vibe-Checked" Skills
Currently, many agent skills are shipped after minimal validation, often consisting of:
- Manual Runs: A few manual executions to see if the skill "works."
- Colleague Approval: A quick review and "thumbs-up" from a colleague.
- AI-Written, Untested: Skills generated by AI without a structured testing framework.
This approach is problematic because AI agents are inherently non-deterministic. It becomes difficult to distinguish between a skill failure caused by a poorly written skill and a failure due to the complexity of the task or the model's current state.
The Solution: A Lightweight Eval Harness
Schmid advocates for a full lifecycle approach to building reliable agent skills, including a lightweight evaluation harness. This harness is crucial for catching failures before they reach end-users.
- Defining a "Skill": Understanding what constitutes a "skill" is the first step. It's not just a function; it's a component designed to be invoked by an AI agent to perform a specific task.
- Correct Triggering: A key aspect of skill development is ensuring that the agent triggers the skill correctly and under the right conditions.
- Catching Failures Early: A robust evaluation process helps to identify issues related to skill logic, parameter handling, and output validation, thus preventing common production failures.
Skill Bench: A Popular Benchmark
Tools like Skill Bench are valuable for understanding the landscape of existing agent skills. By analyzing tens of thousands of skills, it's become apparent that the vast majority lack proper evals, highlighting the widespread nature of this issue.
Key Takeaway for Developers
For developers building or integrating agent skills into their applications, the message is clear: Do not ship skills without proper evaluations. Implementing a systematic approach to testing agent skills, similar to how code is tested, is essential for building reliable and trustworthy AI-powered applications.