ruby-on-rails - 如何重写类范围内声明的方法?

标签 ruby-on-rails ruby methods scope overriding

我正在使用 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_somethinghas_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/

相关文章:

ruby-on-rails - rails : self join scheme with has_and_belongs_to_many?

ruby - 优雅地将字符串放在同一行

ruby-on-rails - 如何在 Nokogiri 中创建具有属性和值的 xml 元素

c# - C# 中方法的返回类型

c++ - 虚函数间共享代码

ruby - Ruby 中最简洁/优雅/合适的方法参数解析

ruby-on-rails - Mailgun 帐户注册后很快就被禁用

ruby-on-rails - rails : Using CanCan to assign multiple roles to Users for each organization they belong to?

ruby-on-rails - 设置属性未定义方法

ruby-on-rails - 由于 unicorn ,bundle exec rails s 失败