0

基本グループ モデル:

class Group < ActiveRecord::Base
  @@ItemType = 'GroupItem' # Base ItemType
  after_initialize :default_item_type

  has_many :group_assignments
  has_many :items, through: :group_assignments, source: :groupable, source_type: @@ItemType, dependent: :destroy

  accepts_nested_attributes_for :items, allow_destroy: true

  private
  def default_item_type
    self.item_type = @@ItemType if self.new_record?
  end
end

名前空間モデル:

class Gradation::Group < Group
  @@ItemType = 'Gradation' # Base ItemType
  after_initialize :default_item_type

  has_many :group_assignments
  has_many :items, through: :group_assignments, source: :groupable, source_type: @@ItemType, dependent: :destroy

  accepts_nested_attributes_for :items, allow_destroy: true
  private
  def default_item_type
    self.item_type = @@ItemType if self.new_record?
  end
end

*after_initialize* コールバックで *item_type* フィールドを設定しようとしていますが、何をしても、コールバックは通常のグループ モデルでのみトリガーされ、名前空間モデルではトリガーされません。

これが予想される動作である理由と、名前空間が設定されたGroupに対してコールバックを機能させる方法を理解するのに苦労しています。

4

2 に答える 2

0

ここでクラス変数を使用しても、@@ItemType = 'Gradation'おそらく役に立ちません。この問題の最初のモデル化では、@@ItemType は互いに足を踏み入れ、常に「グラデーション」を与えていました。

以下が機能します。違いに気付くでしょう:

  1. クラス変数の代わりにクラスの定数に移動
  2. 名前空間を変更しました

アプリ/モデル/group.rb

class Group < ActiveRecord::Base
  ITEM_TYPE = 'GroupItem' # Base ItemType
  after_initialize :default_item_type

  private
  def default_item_type
    self.item_type = ITEM_TYPE if self.new_record?
  end
end

アプリ/モデル/グループ/gradation.rb

class Group::Gradation < Group
  ITEM_TYPE = 'Gradation' # Base ItemType

  private
  def default_item_type
    self.item_type = ITEM_TYPE if self.new_record?
  end
end

ノート:

  1. ここで SingleTableInheritance を使用することはできません -- Rails はグラデーション テーブルがあることを想定しています。
  2. default_item_type正しい ITEM_TYPE をプルできるように、各サブクラスで定義する必要があります

上記の #2 を取り除くには、次のようにします。

class Group < ActiveRecord::Base
  ITEM_TYPE = 'GroupItem' # Base ItemType
  after_initialize :default_item_type

  private
  def default_item_type
    self.item_type = "#{self.class}::ITEM_TYPE".constantize if self.new_record?
  end
end

次に、各サブクラスは次のようになります。

class Group::Graduation < Group
  ITEM_TYPE = 'Graduation' # Base ItemType  
end
于 2013-08-12T14:00:27.373 に答える
-1

私の問題に対する全体的な解決策は次のようになります...

基本グループ モデル:

class Group < ActiveRecord::Base
  @@ItemType = 'GroupItem' # Base ItemType
  after_initialize :default_item_type

  has_many :group_assignments
  has_many :items, through: :group_assignments, source: :groupable, source_type: @@ItemType, dependent: :destroy

  accepts_nested_attributes_for :items, allow_destroy: true

  private
  def default_item_type
    self.item_type = @@ItemType if self.new_record?
  end
end

別の任意のモデルに設定された ItemType を持つサブクラス化されたグループ モデル (app/models/groups/gradation_group.rb 内):

class Groups::GradationGroup < Group
  @@ItemType = 'Gradation'
  has_many :items, through: :group_assignments, source: :groupable, source_type: @@ItemType, dependent: :destroy
end

私の理解では、名前空間をクラス名ではないものに変更する必要がありました。また、グループ名を、アイテムの関連付けを構成するもの以外の名前(この場合はGradation ) に変更する必要がありました。

于 2013-08-12T15:43:58.437 に答える