0

Основная группа Модель:Rails Namespaced модель не вызывает Callbacks

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 Модель:

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 

Я пытаюсь иметь поле * item_type * быть установлен на * after_initialize * обратного вызова, но неважно, что я делаю, обратный вызов запускается только по обычной групповой модели, а не по имени.

Я боюсь понять, почему это ожидаемое поведение, а также как получить обратные вызовы для работы с именами Группа.

+0

Возможно, это странно, но вы можете изменить 'private' на' protected'?Если я хорошо помню, частные методы могут использоваться только Model, а защищенные методы могут использоваться моделью и ее унаследованными классами. Кроме того, callback 'after_initialize' будет называться много раз! Он будет вызываться каждый раз, когда вы будете получать запись. Если вы хотите установить значение по умолчанию на этапе создания записи, вместо этого используйте 'before_create';) – MrYoshiji

ответ

-1

Общее решение моей проблемы выглядит так ...

Base Group Модель:

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 установлен на другой произвольной модели (в приложение/модели/группы/gradation_group.rb):

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

Я понимаю, я должен был изменить пространство имен на то, что не класс п AME. Мне также пришлось изменить название группы на что-то другое, кроме того, что будет связано с ассоциацией : (в данном случае Градация).

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 
Смежные вопросы