如何覆盖类范围中陈述的方法?

时间:2012-10-28 13:45:50

标签: ruby-on-rails ruby methods scope override

我正在使用Ruby 1.9.2和Ruby on Rails 3.2.2。我有以下声明:

class Category < ActiveRecord::Base
  include Commentable

  acts_as_list :scope => 'category_comment_id'

  has_many :comments, :class_name => 'CategoryComment'

  # ...
end

module Commentable
  extend ActiveSupport::Concern

  included do
    acts_as_list :scope => 'comment_id'

    has_many :comments, :class_name => 'Comment'

    # Other useful method statements...
  end

  # Other useful method statements...
end

在上面的代码中,我尝试覆盖包含acts_as_something模块添加到has_many类的CategoryCommentable方法。这两种方法都在“Category的范围内声明,因此上面的代码按预期工作:方法不会被覆盖。

是否可以覆盖这些方法?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:2)

您应该在类定义的末尾包含您的模块。就像现在一样,模块中的方法在类定义其方法之前被注入。这是因为ruby以自上而下的方式处理和评估代码。因此,稍后它会遇到类自己的方法定义并覆盖来自模块的那些。

所以,根据你的意图使用这些知识:谁应该超越谁。如果模块中的方法应该优于类中的方法,那么最后将它包含在内。

修改

鉴于此代码

require 'active_support/core_ext'

class Base
  def self.has_many what, options = {}
    define_method "many_#{what}" do
      "I am having many #{what} with #{options}"
    end
  end
end

module Commentable
  extend ActiveSupport::Concern

  included do
    has_many :comments, class_name: 'Comment'
  end
end

然后

class Foo < Base
  include Commentable
  has_many :comments
end

# class overrides module
Foo.new.many_comments # => "I am having many comments with {}"

class Foo < Base
  has_many :comments
  include Commentable
end

# module overrides class 
Foo.new.many_comments # => "I am having many comments with {:class_name=>\"Comment\"}"