0

Basic Group Model:

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

Namespaced Model:

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

I am attempting to have a field *item_type* be set on the *after_initialize* callback, but not matter what I do, the callback is only triggered on the regular group model and not the namespaced one.

I am struggling to understand why this is the expected behavior, and also how to get callbacks to work for the namespaced 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

应用程序/模型/组/渐变.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 设置为另一个任意模型的子类 Group 模型(在 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 回答