简体   繁体   English

Rails:如何扩展gem的ActiveRecord子类?

[英]Rails: how to extend a gem's ActiveRecord child class?

Im having problems extending a class which is defined in a gem and is a child of ActiveRecord::Base. 我在扩展一个在gem中定义的类并且是ActiveRecord :: Base的子类时遇到了问题。

The only thing i'd like to extend this class with is: has_many :promos 我唯一想扩展这个类的是: has_many :promos

The extending however tends to rule out the original class. 然而,扩展倾向于排除原始类。 The errors i'm getting: 我得到的错误:

PGError: ERROR:  relation "sites" does not exist
LINE 4:              WHERE a.attrelid = '"sites"'::regclass
                                        ^
:             SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
              FROM pg_attribute a LEFT JOIN pg_attrdef d
                ON a.attrelid = d.adrelid AND a.attnum = d.adnum
             WHERE a.attrelid = '"sites"'::regclass
               AND a.attnum > 0 AND NOT a.attisdropped
             ORDER BY a.attnum

Checking the class in the console gives: 检查控制台中的类给出:

Cms::Site(Table doesn't exist)

The original class has this method which probably isn't invoked anymore: 原始类有这个方法,可能不再被调用:

set_table_name :cms_sites

Btw. 顺便说一句。 i'm trying to extend the Site class from the comfortable_mexican_sofa plugin. 我正在尝试从comfortable_mexican_sofa插件扩展Site类。

This is the file which should extend the class: 这是应该扩展类的文件:

# lib/comfortable_media_sofa/comfortable_media_sofa.rb
require 'comfortable_mexican_sofa'

module Cms
  class Site < ActiveRecord::Base
    has_many :promos
  end
end

Which gets loaded here: 哪个在这里加载:

require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(:default, Rails.env) if defined?(Bundler)

module Mkturbo
  class Application < Rails::Application
    config.autoload_paths += %W(#{config.root}/vendor/gems/comfortable_mexican_sofa-0.0.18)
    config.autoload_paths += %W(#{config.root}/lib/comfortable_media_sofa)
    config.plugins = [ :comfortable_mexican_sofa, :comfortable_media_sofa, :all ]

    # ....
  end
end

And is required in the top of the comfortable_mexican_sofa initializer: 并且在comfortable_mexican_sofa初始化程序的顶部是必需的:

# config/initializers/comfortable_mexican_sofa.rb
require 'comfortable_media_sofa'

How can i do this? 我怎样才能做到这一点? Is a requirement order issue or am i extending it the wrong way? 是需求订单问题还是我以错误的方式扩展? Many thanks in advance! 提前谢谢了!

In your example you're completely overwriting that class. 在你的例子中,你完全覆盖了那个类。 You just need to inject things into it... something like this: 你只需要把东西注入其中......就像这样:

module MyModule
  def self.included(base)
    base.has_many :things
  end
end
Cms::Site.send(:include, MyModule)

Then just to see if the association kicks in: 然后,只是为了看看协会是否开始:

ruby-1.9.2-p180 :005 > s = Cms::Site.new
=> #<Cms::Site id: nil, label: nil, hostname: nil> 
ruby-1.9.2-p180 :006 > s.things
NameError: uninitialized constant Cms::Site::Thing

I actually put that module directly into sofa's initializer. 我实际上将该模块直接放入沙发的初始化器中。 Hope this helps. 希望这可以帮助。

The most obvious thing that jumps out at me is that you say you're "trying to extend the Site class from the comfortable-mexican-sofa plugin" 跳出来的最明显的事情就是你说你“试图从舒适的墨西哥沙发插件中扩展Site类”

...but the class in your module is extending ActiveRecord::Base. ...但是模块中的类正在扩展ActiveRecord :: Base。

module Cms    
  class Site < ActiveRecord::Base
  ...

Maybe I'm reading it wrong, but it sounds like your class should be something like: 也许我读错了,但听起来你的课应该是这样的:

module Cms      
  class Site < CmsSite  // i.e. extending the class from comfortable-mexican-sofa
  ...

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

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