gpt4 book ai didi

ruby-on-rails - ActiveRecord::Migration 前置上下文和方法

转载 作者:数据小太阳 更新时间:2023-10-29 08:06:41 25 4
gpt4 key购买 nike

我正在构建一个库以向 ActiveRecord::Migration 添加功能但我很难理解这种行为。

加载库后,我执行以下代码

ActiveSupport.on_load(:active_record) do
ActiveRecord::Migration.prepend MyLibrary::Mutators
end

然后在my_library/mutators.rb

module MyLibrary
module Mutators
def do_something
# do stuff here and use `self`
end
end
end

这里的目标非常简单,我需要能够在我的迁移类中调用这个方法

class Test < ActiveRecord::Migration[5.2]
do_something

def change
create_table 'async_test' do |t|
t.string :test
end
end
end

当我运行这个迁移时,它会有效地调用 do_something

问题是当我尝试获取有关运行内容的上下文时,这是我的库执行其他内容所必需的,selfActiveRecord::Migration 的实例而不是 Test , 但使用此方法的类是 Test .

#<ActiveRecord::Migration:0x00007fac5b83df38
@connection=nil,
@name="ActiveRecord::Migration",
@version=nil>

如果我改变现状并调用 do_something#change 内它会考虑 self作为 Test 的实例这正是我在类里面所希望的。

我怎样才能得到 do_something返回 self作为Test在类级别通过扩展 ActiveRecord::Migration

最佳答案

ActiveRecord::Migration.method_missing (在类里面)调用 nearest_delegate这似乎是 ActiveRecord::Migration

的一个实例
 > ActiveRecord::Migration.nearest_delegate
=> #<ActiveRecord::Migration:0x0000561889aa1930 @connection=nil, @name="ActiveRecord::Migration", @version=nil>

当您调用 ActiveRecord::Migration.prepend MyLibrary::Mutators 时,您在 ActiveRecord::Migration 的实例方法前面添加了 MyLibrary::Mutators。所以 do_something 是在迁移实例上定义的。

当你打电话时:

class Test < ActiveRecord::Migration[5.2]
do_something
# ...
end

Test.method_missing 被调用,它在 nearest_delegate 上调用 #do_something 似乎是 ActiveRecord::Migration 实例。

如果你想在迁移类级别真正定义do_something,你需要适本地预先添加类方法。在对 this question 的回答中对此进行了精确描述.

长话短说,你应该在迁移单例类中调用 .prepend,而不是在迁移类中:

ActiveSupport.on_load(:active_record) do
ActiveRecord::Migration.singleton_class.prepend MyLibrary::Mutators
end

关于ruby-on-rails - ActiveRecord::Migration 前置上下文和方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54043317/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com