0

こんにちは私はしばらくの間これの解決策を探していました。Rails2.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)]
>> 

子クラスをすべて1つの巨大なファイルに戻すなど、これに対するあまり洗練されていない解決策があると確信していますが、可能な限りこれを避けたいと思います。

ありがとう

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 に答える