我正在使用 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
添加到 Category
的方法类包括 Commentable
模块。这两种方法都被规定为“在 Category
的范围内”所以上面的代码没有按预期工作:方法没有被覆盖。
是否可以重写这些方法?如果是这样,怎么办?
最佳答案
您应该将模块包含在类定义的末尾。就像现在一样,模块中的方法在类定义其方法之前被注入(inject)。之所以如此,是因为 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\"}"
关于ruby-on-rails - 如何重写类范围内声明的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13109289/