简体   繁体   English

在rails模型中重新定义gem方法不起作用

[英]redefining gem method in rails model not working

So I have a gem that contains some activerecord models that gets used by multiple applications on our platform. 所以我有一个包含一些activerecord模型的gem,它们被我们平台上的多个应用程序使用。 We had a constant defining a list of "types" that was divergent on a couple different applications. 我们有一个常量定义了一个“类型”列表,这些列表在几个不同的应用程序上有所不同。

# in the gem
class MyModel < ActiveRecord::Base
  TYPES = ["A Type", "Another Type"]
end

Redefining this constant in the application code will generate a warning for an already initalized constant. 在应用程序代码中重新定义此常量将为已经初始化的常量生成警告。 So since it's not really constant, I decided to refactor it to a class method. 因为它不是真的不变,所以我决定将它重构为类方法。

# gem
class MyModel < ActiveRecord::Base
  def self.types
    []
  end
end

# application a
class MyModel < ActiveRecord::Base
  def self.types
    ["A Type", "D Type"]
  end
end

# application b
class MyModel < ActiveRecord::Base
  def self.types
    ["B Type", "C Type"]
  end    
end

However, when accessing MyModel.types in App A or B, types is [] . 但是,在App A或B中访问MyModel.types时,类型为[] This, and a few other issues, have lead me to conclude that the gem is loaded after the rails app is loaded, while my assumption was the opposite. 这个以及其他一些问题让我得出结论,在加载rails应用程序之后加载了gem,而我的假设恰恰相反。

what would be the best way to handle a divergent case such as this? 什么是处理这种不同情况的最佳方法?

Do this in your applications 在您的应用中执行此操作

Create a file in your config/initializers/ and add this code in both your apps config/initializers/创建一个文件,并在您的应用中添加此代码

MyModel.instance_eval do
  def types
    ["A Type", "D Type"]
  end
end

or 要么

MyModel.class_eval do
  def self.types
    ["A Type", "D Type"]
  end
end

You must require the initial class explicitly from your engine, this will ensure it is loaded. 您必须从引擎中明确要求初始类,这将确保它已加载。 Which is sometimes not the case in development ( autoload for instance) 在开发中有时不是这种情况(例如autoload

require YourEngine::Engine.root.join('app/models/your_namespace/my_model')

class MyModel  #no inheritance here, we just reopen an existing class, right?
   def self.types
     [] #override it as you like
   end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM