gpt4 book ai didi

ruby-on-rails - Rails 猴子补丁仅在某些列上

转载 作者:行者123 更新时间:2023-12-05 03:14:24 26 4
gpt4 key购买 nike

我试图仅在子类具有特定列时才包含模块,我正在初始化程序中执行此操作:

 class ActiveRecord::Base
def self.inherited(subclass)
subclass.include(MultiTenancy) if subclass.new.respond_to?(:tenant_id)
end
end

我一直收到这个错误:

NoMethodError: undefined method `[]' for nil:NilClass

这是我要导入的模块:

module MultiTenancy
class TenantNotSetError < StandardError ; end

def self.included(model)
model.class_eval do
belongs_to :tenant
validates :tenant_id, presence: true
default_scope -> {
raise TenantNotSetError.new unless Tenant.current_tenant
where(tenant_id: Tenant.current_tenant.id)
}

def multi_tenanted?
true
end
end
end
end

我做错了什么。我可以将模块包含在任何单独的子类中,例如。 Klass.include(MultiTenancy) 成功,所以问题出在初始化程序上。

下面是堆栈跟踪:

from -e:1:in `<main>'2.1.1 :002 > Klass.all
NoMethodError: undefined method `[]' for nil:NilClass
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:9:in `relation_delegate_class'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:112:in `relation_class_for'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/relation/delegation.rb:106:in `create'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activerecord-4.1.4/lib/active_record/model_schema.rb:133:in `table_name='
from /home/lee/Code/mobifit/app/models/klass.rb:25:in `<class:Klass>'
from /home/lee/Code/mobifit/app/models/klass.rb:22:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:443:in `load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:443:in `block in load_file'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:633:in `new_constants_in'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:442:in `load_file'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:342:in `require_or_load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:480:in `load_missing_constant'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:180:in `const_missing'
from (irb):2
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:90:in `start'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/console.rb:9:in `start'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:69:in `console'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/railties-4.1.4/lib/rails/commands.rb:17:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `block in require'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:247:in `require'
from /home/lee/Code/mobifit/bin/rails:8:in `<top (required)>'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `block in load'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:232:in `load_dependency'
from /home/lee/.rvm/gems/ruby-2.1.1/gems/activesupport-4.1.4/lib/active_support/dependencies.rb:241:in `load'
from /home/lee/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from /home/lee/.rvm/rubies/ruby-2.1.1/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
from -e:1:in `<main>'2.1.1 :003 >

最佳答案

如果您稍微跟踪一下堆栈跟踪,您会发现不应该是 nil 的是类的 @relation_delegate_cache。看着the source ,您可以看到这通常在 initialize_relation_delegate_cache 方法中初始化,该方法在 ActiveRecord::Delegation::DelegateCacheinherited Hook 中调用.

ActiveRecord::Base 扩展了这个模块,所以通常一个继承自 ActiveRecord::Base 的类会调用这个继承的钩子(Hook)。所以你的代码的问题是你在 ActiveRecord::Base 上猴子修补 inherited,这意味着 ActiveRecord::Delegation::中的钩子(Hook)DelegateCache 不再被调用。

两条评论:

  1. 这就是为什么猴子补丁不是一个好主意的原因,尤其是像事件记录这样基础和复杂的东西。有没有可能以更直接的方式做您想做的事情?
  2. 如果不是,你应该记下 ActiveRecord::Delegation::DelegateCache 是如何工作的,并重写你的猴子补丁以混合到你自己的模块中,而不是仅仅覆盖 ActiveRecord::Baseinherited方法。

(2) 中的建议看起来像这样:

module MultitenancyConcern

def self.inherited(subclass)
subclass.include(MultiTenancy) if subclass.column_names.include?("tenant_id")
super #this is critical for avoiding the error you're getting
end

end

然后你的猴子补丁就变成了

ActiveRecord::Base.extend(MultitenancyConcern)

关于ruby-on-rails - Rails 猴子补丁仅在某些列上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25016461/

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