-
-
Notifications
You must be signed in to change notification settings - Fork 105
Rails Generator for RubyLLM Models #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The generator creates Chat, Message, and ToolCall models with migrations for seamless Rails integration. Users can run 'rails generate ruby_llm:install' to automatically set up all required models and database tables. - Add install_generator with templates for models and migrations - Update Rails integration guide with generator instructions - Update README with two integration options - Update Railtie to register the generator - Add CLAUDE.md for agent assistance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Added tests for the Rails generator template files to ensure they contain the expected content. Fixed a Zeitwerk warning by ignoring the generators directory in the loader. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Updated the tool_calls migration to detect and use the appropriate JSON column type based on the database adapter: - Uses jsonb for PostgreSQL databases (better performance and indexing) - Falls back to standard json type for other databases (MySQL, SQLite, etc.) - Added postgresql? detection method with proper error handling - Added comprehensive tests for database adapter detection 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
lib/generators/ruby_llm/install/templates/create_tool_calls_migration.rb
Outdated
Show resolved
Hide resolved
This adds a helpful README template that's displayed after successful generator installation, providing users with clear next steps and examples of how to use the generated models. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Addresses PR feedback to remove redundant comments from the migration template. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Renamed all template files to use .tt extension following Rails convention - Updated generator code and tests to reference the new template files - Fixed style issues in the generator code according to Rubocop 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Split large tests into smaller focused tests - Fix string quotes to follow style guidelines - Remove trailing whitespace - Improve test readability and organization 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Removed unnecessary whitespace in railtie.rb for cleaner code. - Added comprehensive tests for the RubyLLM::InstallGenerator to ensure migration and model templates are correctly defined and structured. - Deleted outdated template files spec to streamline test organization. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
I created a PR on this PR (not sure where to put it so commenting here). This PR adds to this one by allowing the user to pass in the class (and hence table) names for the Here is an example:
|
Amazing! Thanks @jamster once merge conflicts are resolved I'll merge it |
readme as template, migration # handled by rails, remove `frozen_literal` from models and migrations forcing timestamp order for migrations make act_as methods dynamic, cleaned ordering/references
Making class and table names optional
Ok ready for review! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be annoying to have a new README? I would delete this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the name "README" is a bit misleading here. This is the text generated AFTER you run the generator to explain what you did, whereas the readme for RubyLLM remains the same and untouched. Originally, this did overwrite the README, but has been corrected to be more of an ephemeral display post install.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you can see it in the test added too. It's to give direction after using the generator.
@@ -0,0 +1,16 @@ | |||
# This migration must be run AFTER create_<%= options[:chat_model_name].tableize %> and create_<%= options[:tool_call_model_name].tableize %> migrations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to enforce this constraint with the timestamp of the migration? Disclaimer: I'm new to making templates for migrations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments on latest PR below
def create_migration_files | ||
# Use a fixed timestamp for testing and to ensure they're sequential | ||
# @migration_number = Time.now.utc.strftime('%Y%m%d%H%M%S') | ||
migration_template 'create_chats_migration.rb.tt', "db/migrate/create_#{options[:chat_model_name].tableize}.rb" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah there you go that's where we can enforce the order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kieranklaassen can you enforce the order by using timestamps in the name just like rails does?
ruby_llm.gemspec
Outdated
# Add generator files | ||
spec.files += Dir.glob('lib/generators/**/*') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be already covered by the lines above
ruby_llm.gemspec
Outdated
|
||
# Development dependencies | ||
spec.add_development_dependency 'rails', '>= 7.0.0' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't add dev dependencies here, we do it in the Gemfile
let(:template_dir) { File.join(File.dirname(__FILE__), '../../../../lib/generators/ruby_llm/install/templates') } | ||
let(:generator_file) { File.join(File.dirname(__FILE__), '../../../../lib/generators/ruby_llm/install_generator.rb') } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
File.dirname(__FILE__)
can be __dir__
right?
Address PR feedback and cleanup - Replace File.dirname(__FILE__) with __dir__ in specs for better Ruby idioms - Remove redundant spec.files line for generators (already covered by lib/**/*) - Move rails development dependency to Gemfile from gemspec - Update example in README to use ActiveJob instead of controller for better practices Note on migration timestamps: The current implementation has no table dependencies, so migration order is not critical. Rails generators automatically handle timestamps for migrations, making manual timestamp management unnecessary.
I've made the updates you requested and created this PR: kieranklaassen#2 for context, the PR addresses: Address PR feedback and cleanup
Note on migration timestamps: The current implementation has no table dependencies, |
Addresses comments in PR
Thanks @jamster !! I've been really busy so appreciate doing the work!! |
@crmne Let me know if you need any more chnages, waiting for review |
21c4ee0
to
fd7e972
Compare
…mprove formatting - Added a section on using the generator for setting up RubyLLM in Rails applications. - Improved formatting for better readability, including table of contents and notes. - Updated examples to reflect changes in model creation and button usage in forms.
…cord creation - Modified examples in the Rails integration guide to reflect the inclusion of the `user` parameter when creating a new chat record. - Updated model_id in examples to 'gpt-4.1-nano' for consistency.
- Introduced the `ChatStreamJob` class to the Rails integration guide, detailing its purpose and functionality in handling chat streaming. - Included comments within the job to explain the process of saving user messages and broadcasting assistant message updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! there are a couple things to change and then I'm ready to merge it
docs/guides/rails.md
Outdated
@@ -7,31 +7,67 @@ permalink: /guides/rails | |||
--- | |||
|
|||
# Rails Integration | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove empty line
docs/guides/rails.md
Outdated
RubyLLM offers seamless integration with Ruby on Rails applications through helpers for ActiveRecord models. This allows you to easily persist chat conversations, including messages and tool interactions, directly in your database. | ||
{: .fs-6 .fw-300 } | ||
RubyLLM offers seamless integration with Ruby on Rails applications through helpers for ActiveRecord models. This allows you to easily persist chat conversations, including messages and tool interactions, directly in your database. {: .fs-6 .fw-300 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stick to previous version
docs/guides/rails.md
Outdated
|
||
## Table of contents | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove empty line
docs/guides/rails.md
Outdated
1. TOC | ||
{:toc} | ||
1. TOC {:toc} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stick to previous version
docs/guides/rails.md
Outdated
* How to set up ActiveRecord models for persisting chats and messages. | ||
* How to use `acts_as_chat` and `acts_as_message`. | ||
* How chat interactions automatically persist data. | ||
* A basic approach for integrating streaming responses with Hotwire/Turbo Streams. | ||
- How to set up ActiveRecord models for persisting chats and messages. | ||
- How to use `acts_as_chat` and `acts_as_message`. | ||
- How chat interactions automatically persist data. | ||
- A basic approach for integrating streaming responses with Hotwire/Turbo Streams. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unnecessary change
docs/guides/rails.md
Outdated
{: .note } | ||
The `acts_as` helpers primarily handle loading history and saving messages/tool calls related to the chat interaction. Add your application-specific logic (associations, validations, scopes, callbacks) as usual. | ||
{: .note } The `acts_as` helpers primarily handle loading history and saving messages/tool calls related to the chat interaction. Add your application-specific logic (associations, validations, scopes, callbacks) as usual. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stick to previous version
docs/guides/rails.md
Outdated
```ruby | ||
# config/initializers/ruby_llm.rb | ||
RubyLLM.configure do |config| | ||
config.openai_api_key = ENV["OPENAI_API_KEY"] | ||
config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"] | ||
# Add other provider keys as needed | ||
end | ||
``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for this, we have the configuration guide for it
docs/guides/rails.md
Outdated
{: .note } | ||
This example shows the core idea. You'll need to adapt the broadcasting, targets, and partials for your specific UI needs (e.g., handling Markdown rendering, adding styling, showing typing indicators). See the [Streaming Responses Guide]({% link guides/streaming.md %}) for more on streaming itself. | ||
{: .note } This example shows the core idea. You'll need to adapt the broadcasting, targets, and partials for your specific UI needs (e.g., handling Markdown rendering, adding styling, showing typing indicators). See the [Streaming Responses Guide]({% link guides/streaming.md %}) for more on streaming itself. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stick to previous version
docs/guides/rails.md
Outdated
* [Chatting with AI Models]({% link guides/chat.md %}) | ||
* [Using Tools]({% link guides/tools.md %}) | ||
* [Streaming Responses]({% link guides/streaming.md %}) | ||
* [Working with Models]({% link guides/models.md %}) | ||
* [Error Handling]({% link guides/error-handling.md %}) No newline at end of file | ||
- [Chatting with AI Models]({% link guides/chat.md %}) | ||
- [Using Tools]({% link guides/tools.md %}) | ||
- [Streaming Responses]({% link guides/streaming.md %}) | ||
- [Working with Models]({% link guides/models.md %}) | ||
- [Error Handling]({% link guides/error-handling.md %}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stick to previous version
def create_migration_files | ||
# Use a fixed timestamp for testing and to ensure they're sequential | ||
# @migration_number = Time.now.utc.strftime('%Y%m%d%H%M%S') | ||
migration_template 'create_chats_migration.rb.tt', "db/migrate/create_#{options[:chat_model_name].tableize}.rb" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kieranklaassen can you enforce the order by using timestamps in the name just like rails does?
lib/ruby_llm/railtie.rb
Outdated
@@ -8,5 +8,15 @@ class Railtie < Rails::Railtie | |||
include RubyLLM::ActiveRecord::ActsAs | |||
end | |||
end | |||
|
|||
# Include rake tasks if applicable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should include the ruby_llm rake tasks in a Rails application:
rake_tasks do
path = File.expand_path(__dir__)
Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an issue for the rake task not show up in a Rails application: #136
This is making it harder for me to use the latest Gemini models.
… railtie.rb, and revert rails.md changes
This PR adds a Rails generator for RubyLLM models, making it easier to integrate RubyLLM with Rails applications.
Changes in this PR
Recent updates to address PR comments
Renamed README.md.tt to INSTALL_INFO.md.tt to avoid confusion with the project README, and updated the reference in the install_generator.rb file.
Fixed migration order by using timestamps in the migration filenames in the install_generator.rb file. This ensures that migrations run in the correct order (chats first, then tool_calls, then messages).
Updated railtie.rb to include rake tasks from the lib/ruby_llm/tasks directory, which addresses the issue mentioned in the comments about rake tasks not showing up in Rails applications.
Reverted several changes in docs/guides/rails.md as requested in the comments, including fixing formatting issues and removing unnecessary content.
Removed the comment about migration order from the create_messages_migration.rb.tt file since we're now enforcing it with timestamps.
These changes should address all the issues mentioned in the PR comments.