Skip to content

Commit 1678ea5

Browse files
authored
Use foreign_key instead of to_s for acts_as methods (#157)
1 parent b4cd7d0 commit 1678ea5

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

lib/ruby_llm/active_record/acts_as.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ def acts_as_chat(message_class: 'Message', tool_call_class: 'ToolCall')
2424
to: :to_llm
2525
end
2626

27-
def acts_as_message(chat_class: 'Chat', tool_call_class: 'ToolCall', touch_chat: false) # rubocop:disable Metrics/MethodLength
27+
def acts_as_message(chat_class: 'Chat', tool_call_class: 'ToolCall', **options) # rubocop:disable Metrics/MethodLength
2828
include MessageMethods
2929

3030
@chat_class = chat_class.to_s
31-
@chat_foreign_key = "#{@chat_class.underscore}_id"
31+
@chat_foreign_key = options[:chat_foreign_key] || @chat_class.foreign_key
3232
@tool_call_class = tool_call_class.to_s
33-
@tool_call_foreign_key = "#{@tool_call_class.underscore}_id"
33+
@tool_call_foreign_key = options[:tool_call_foreign_key] || @tool_call_class.foreign_key
3434

3535
belongs_to :chat,
3636
class_name: @chat_class,
3737
foreign_key: @chat_foreign_key,
3838
inverse_of: :messages,
39-
touch: touch_chat
39+
touch: options[:touch_chat]
4040

4141
has_many :tool_calls,
4242
class_name: @tool_call_class,
@@ -51,9 +51,9 @@ def acts_as_message(chat_class: 'Chat', tool_call_class: 'ToolCall', touch_chat:
5151
delegate :tool_call?, :tool_result?, :tool_results, to: :to_llm
5252
end
5353

54-
def acts_as_tool_call(message_class: 'Message') # rubocop:disable Metrics/MethodLength
54+
def acts_as_tool_call(message_class: 'Message', **options) # rubocop:disable Metrics/MethodLength
5555
@message_class = message_class.to_s
56-
@message_foreign_key = "#{@message_class.underscore}_id"
56+
@message_foreign_key = options[:message_foreign_key] || "#{@message_class.underscore}_id"
5757

5858
belongs_to :message,
5959
class_name: @message_class,

spec/ruby_llm/active_record/acts_as_spec.rb

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,12 @@ class Chat < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock
7474
acts_as_chat
7575
end
7676

77-
class BotChat < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration
78-
include RubyLLM::ActiveRecord::ActsAs
79-
acts_as_chat message_class: 'BotMessage', tool_call_class: 'BotToolCall'
77+
module Assistants # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration
78+
class BotChat < ActiveRecord::Base # rubocop:disable RSpec/LeakyConstantDeclaration
79+
self.table_name = 'bot_chats'
80+
include RubyLLM::ActiveRecord::ActsAs
81+
acts_as_chat message_class: 'BotMessage', tool_call_class: 'BotToolCall'
82+
end
8083
end
8184

8285
class Message < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration
@@ -86,7 +89,7 @@ class Message < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBl
8689

8790
class BotMessage < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration
8891
include RubyLLM::ActiveRecord::ActsAs
89-
acts_as_message chat_class: 'BotChat', tool_call_class: 'BotToolCall'
92+
acts_as_message chat_class: 'Assistants::BotChat', tool_call_class: 'BotToolCall'
9093
end
9194

9295
class ToolCall < ActiveRecord::Base # rubocop:disable Lint/ConstantDefinitionInBlock,RSpec/LeakyConstantDeclaration
@@ -115,7 +118,7 @@ def execute(expression:)
115118

116119
shared_examples 'a chainable chat method' do |method_name, *args|
117120
it "returns a Chat instance for ##{method_name}" do
118-
[Chat, BotChat].each do |chat_class|
121+
[Chat, Assistants::BotChat].each do |chat_class|
119122
chat = chat_class.create!(model_id: 'gpt-4.1-nano')
120123
result = chat.public_send(method_name, *args)
121124
expect(result).to be_a(chat_class)
@@ -125,7 +128,7 @@ def execute(expression:)
125128

126129
shared_examples 'a chainable callback method' do |callback_name|
127130
it "supports #{callback_name} callback" do # rubocop:disable RSpec/ExampleLength
128-
[Chat, BotChat].each do |chat_class|
131+
[Chat, Assistants::BotChat].each do |chat_class|
129132
chat = chat_class.create!(model_id: 'gpt-4.1-nano')
130133
result = chat.public_send(callback_name) do
131134
# no-op for testing
@@ -172,7 +175,7 @@ def execute(expression:)
172175

173176
describe 'with_tools functionality' do
174177
it 'returns a Chat instance when using with_tool' do
175-
[Chat, BotChat].each do |chat_class|
178+
[Chat, Assistants::BotChat].each do |chat_class|
176179
chat = chat_class.create!(model_id: 'gpt-4.1-nano')
177180
with_tool_result = chat.with_tool(Calculator)
178181
expect(with_tool_result).to be_a(chat_class)
@@ -196,7 +199,7 @@ def execute(expression:)
196199
it_behaves_like 'a chainable callback method', :on_end_message
197200

198201
it 'supports method chaining with tools' do # rubocop:disable RSpec/ExampleLength
199-
[Chat, BotChat].each do |chat_class|
202+
[Chat, Assistants::BotChat].each do |chat_class|
200203
chat = chat_class.create!(model_id: 'gpt-4.1-nano')
201204
chat.with_tool(Calculator)
202205
.with_temperature(0.5)

0 commit comments

Comments
 (0)