0

您好,我一直在寻找解决此问题的方法。使用 Rails 2.3.5

我有一个包含几个子类的父类,为了没有一个 1500 行长的文件,我将子类保存在 app/models 目录的子目录中。

直到最近,当我查看这篇文章时:这里

我什至无法加载子类

现在我想使用 self.inherited 类方法访问每个孩子,如下所示:

class Project < ActiveRecord::Base

  CHILDREN = []
  def self.inherited(child)
    super
    CHILDREN << child
    puts "CHILDREN.inspect: #{CHILDREN.inspect}"
  end
  def self.valid_child_types
    CHILDREN.collect{ |child| child.project_type}
  end
end

暂时,我放了一些调试语句来更好地了解事物是如何加载的。我启动了控制台并注意到了这种行为:

>> Project
require_or_load /Users/frankdrebin/Sites/cerp/app/models/project.rb
loading /Users/frankdrebin/Sites/cerp/app/models/project
require_or_load /Users/frankdrebin/Sites/cerp/app/models/status.rb
loading /Users/frankdrebin/Sites/cerp/app/models/status

=> Project(id: integer, url: string, deadline: date, state: string, type: string,  priority: integer, status_id: integer)
>> Project::CHILDREN
=> []
>> ArticleProject
require_or_load /Users/frankdrebin/Sites/cerp/app/models/projects/article_project.rb
loading /Users/frankdrebin/Sites/cerp/app/models/projects/article_project
CHILDREN.inspect: [ArticleProject(id: integer, url: string, deadline: date, state:  string, type: string, priority: integer, status_id: integer)]
require_or_load /Users/frankdrebin/Sites/cerp/vendor/gems/state_machine-  0.7.3/lib/state_machine.rb
loading /Users/frankdrebin/Sites/cerp/vendor/gems/state_machine-0.7.3/lib/state_machine

=> ArticleProject(id: integer, url: string, deadline: date, state: string, type: string,   priority: integer, status_id: integer)
>> Project::CHILDREN
=> [ArticleProject(id: integer, url: string, deadline: date, state: string, type: string,  priority: integer, status_id: integer)]
>> 

我确信对此没有那么优雅的解决方案,例如将子类全部放回一个巨大的文件中,但如果可能的话,我想避免这种情况。

谢谢

4

2 回答 2

1

也许你需要退后一步,问问自己你真正想要完成什么,继承是最好/唯一的方法吗?模块/混合?

于 2011-02-01T23:35:00.290 回答
1

你有各种各样的问题:

  1. CHILDREN 在 Ruby 中是一个常量,因为它以大写字母开头,您不希望这样。
  2. 接下来,如果您将其更改为子类,它将是一个局部变量,但您需要一个实例变量作为父类定义的实例,因此您需要使用@children。
  3. 您需要在班级级别使@children 可用(这可能是您尝试使用 CHILDREN 的原因)。

以下是您的操作方法:

class Parent

  @children = []

  # Make the attr_reader for the class not an instance of the class
  class << self
    attr_reader :children
  end

  def self.inherited(child)
    puts "Parent inherited by child: #{child.inspect}"
    @children << child
    super
  end
end

class Child1 < Parent
end
puts "Child1 class created"

class Child2 < Parent
end
puts "Child2 class created"

c1 = Child1.new
c2 = Child2.new

puts "Parent.children: #{Parent.children}"

输出:

Parent inherited by child: Child1
Child1 class created
Parent inherited by child: Child2
Child2 class created
Parent.children: [Child1, Child2]
于 2011-02-02T00:31:08.833 回答