2009-07-17 2 views
3

У меня есть модель AbstractRecord, из которой сходят некоторые из конкретных моделей (которые имеют свои собственные таблицы). Следующее - наследство.Rails: Как эффективно использовать self.inherited

AbstractRecord < ActiveRecord::Base 
Blog < AbstractRecord 
Post < AbstractRecord 
.... 
.... 

Для того, чтобы Rails искать соответствующие таблицы, если есть наследование, API документы говорят, чтобы определить метод класса abstract_class? который возвращает true, так что рельсы не будут искать свою таблицу. В моем случае, чтобы рельсы искали таблицу блогов (вместо таблицы abstract_records, которая обычно имеет место, как в STI), я определил метод abstract_class? в AbstractRecord, который возвращает true. Кажется, что все запросы работают нормально. Но я вижу, что всякий раз, когда я создаю блог, рельсы показывают его как блог (абстрактный) в консоли, так как его родительский класс возвращает true. Чтобы этого избежать, я мог бы снова определить abstract_class? который возвращает false в классе Blog.

Но я думал вместо определения abstract_class? во всех дочерних моделях, если бы я мог каким-то образом использовать self.inherited и определить этот метод в самом AbstractClass. Я пытался использовать несколько подходов (далее), ни один из них не работает.

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.instance_eval do 
    define_method(:abstract_class?) { false } 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    define_method(:abstract_class?) { false } 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.instance_eval do 
    def abstract_class? 
    false 
    end 
    end 
end 
end 

class AbstractRecord < ActiveRecord::Base 
def self.abstract_class? 
    true 
end 

def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    def abstract_class? 
    false 
    end 
    end 
end 
end 

Любые рекомендации о том, что я делаю неправильно ценится?

ответ

1
class Account < Foo::Bar::Base 
end 

module Foo 
    module Bar 
    class Base < ::ActiveRecord::Base 
     def self.abstract_class? 
     true 
     end 
    end 
    end 
end 

Это прекрасно работает для меня. Это приводит к тому, что «учетные записи» имен таблиц, как и должно быть.

2

Попробуйте это:


def self.inherited(subclass) 
    super 
    def subclass.abstract_class? 
    false 
    end 
end 

Или:


def self.inherited(subclass) 
    super 
    subclass.class_eval do 
    def self.abstract_class? 
    # You lost the 'self' part, so you had just defined an instant method for the subclass 
     false 
    end 
    end 
end 

+0

Голосование вниз из-за не получение 'унаследованный' имя метода правильно! –

+0

@BillEisenhauer Почему бы просто не предложить править, а не голосовать? – Nick

+0

@ Ник, я понятия не имею! Вы спрашиваете о том, какое действие я предпринял почти 5 лет назад. Может быть, я не знал, как предложить редактирование в то время? Вероятно, я знал, что ответ был неправильным и хотел заверить, что другие не смущены. –

Смежные вопросы