Skip to content

Conversation

andreaslillebo
Copy link

First of all, thank you very much for all the effort you put into this gem. It is amazing. 🚀

What this does

Version 1.8.2 breaks namespaced models with custom foreign keys. Consider the following example:

ActiveRecord::Migration.create_table :support_conversations, force: true do |t|
  t.string :model_id
  t.timestamps
end

ActiveRecord::Migration.create_table :support_messages, force: true do |t|
  t.references :conversation, foreign_key: { to_table: :support_conversations }
  t.string :role
  t.text :content
  t.string :model_id
  t.integer :input_tokens
  t.integer :output_tokens
  t.references :tool_call, foreign_key: { to_table: :support_tool_calls }
  t.timestamps
end

ActiveRecord::Migration.create_table :support_tool_calls, force: true do |t|
  t.references :message, foreign_key: { to_table: :support_messages }
  t.string :tool_call_id
  t.string :name
  t.json :arguments
  t.timestamps
end
module Support
  def self.table_name_prefix
    'support_'
  end

  class Conversation < ActiveRecord::Base
    acts_as_chat message_class: 'Support::Message'
  end

  class Message < ActiveRecord::Base
    acts_as_message chat: :conversation, chat_class: 'Support::Conversation', tool_call_class: 'Support::ToolCall'
  end

  class ToolCall < ActiveRecord::Base
    acts_as_tool_call message_class: 'Support::Message'
  end
end
Support::Conversation.last.messages
=> #<ActiveRecord::StatementInvalid:"PG::UndefinedColumn: ERROR:  column support_messages.support_conversation_id does not exist

It does not work, since the correct foreign key should have been support_messages.conversation_id.

I have added a test showcasing this and implemented a fix.

Since we cannot infer foreign keys automatically when it doesn't match the model-name, we expose options to pass in a foreign key, similarly to associations in Rails:

class Support::Message < ActiveRecord::Base
  acts_as_message chat_class: 'Conversation',
                  chat_foreign_key: 'conversation_id'
end

Generators have also been updated to add foreign keys if needed.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Performance improvement

Scope check

  • I read the Contributing Guide
  • This aligns with RubyLLM's focus on LLM communication
  • This isn't application-specific logic that belongs in user code
  • This benefits most users, not just my specific use case

Quality check

  • I ran overcommit --install and all hooks pass
  • I tested my changes thoroughly
    • For provider changes: Re-recorded VCR cassettes with bundle exec rake vcr:record[provider_name]
    • All tests pass: bundle exec rspec
  • I updated documentation if needed
  • I didn't modify auto-generated files manually (models.json, aliases.json)

API changes

  • Breaking change
  • New public methods/classes
  • Changed method signatures
  • No API changes

Related issues

Fixes bug introduced in #425

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant