2015-01-25 3 views
0

EDIT: жаль, что я забыл упомянуть, что я использовал Mongoid тех field были Mongoid техполе доступа дети-классы

У меня есть приложение рельсы, которое отвечает за создание документов Word (и заменяя некоторые переменные внутри)

Так что у меня много DocumentEtude::xxxx классов, суперкласс базового класса DocumentEtude (на английском языке) ProjectDocument

class DocumentEtude 
    include Mongoid::Document 
    field :shared_field 
class DocumentEtude:xxxx < DocumentEtude 
    field :only_in_xxxx_field 

для того, чтобы сохранить свое здравомыслие, я хотел бы иметь всю в riables в одном месте, и сделать что-то вроде этого

class DocumentEtude 
    ... 
    def variables 
      vars = {} 
      case _type 
      when 'DocumentEtude::xxxxx', 'DocumentEtude::yyyyyy', 'DocumentEtude::zzzzzz' 
       vars.merge!({ 
        "some_var" => shared_field, 
        "some_var2" => only_in_xxxx_field 
        ... 
    end 

    def generate_document 
     # Code that uses the variables defined before 
    end 

Теперь проблема заключается в том, что я объявляю этот метод внутри DocumentEtude, однако мне нужно открыть несколько полей, которые только объявленным в дочерних классах (only_in_xxxx_field, например) , но, по-видимому, Ruby не может их найти. Любая идея, как я мог это сделать?

+0

Можете ли вы привести пример того, как вы хотите получить к ним доступ? – Edward

+0

Я повторно задал свой вопрос. Например, у меня может быть «DocumentEtude :: Bill», где у меня есть дополнительные поля «цена», «налог» и т. Д. И я хотел бы поместить эти переменные внутри хэша (который затем используется для замены содержимого в xml мои слова документы) –

+1

Есть ли что-то не так с методом класса 'fields' или методом экземпляров' attributes'? Разве вы не можете начать с них и отфильтровывать обычных подозреваемых? –

ответ

1

Если я понимаю ваш вопрос, вы хотите иметь какие-то настройки, которые наследуются по иерархии классов. Если это так, используйте расширение ядра ActiveSupport class_attribute. Например (копируется из rails guide:

class A 
    class_attribute :x 
end 

class B < A; end 

class C < B; end 

A.x = :a 
B.x # => :a 
C.x # => :a 

B.x = :b 
A.x # => :a 
C.x # => :b 

C.x = :c 
A.x # => :a 
B.x # => :b 

Единственное, что вы должны быть в курсе является mutables (например, хэш, что ваши использует) Но так как в вашем случае это даже желательно для подкласса, чтобы перезаписать. значения суперкласса, вы хорошо идти.

+0

Извините, что я не говорил о class_attributes, кроме экземпляров. Однако я не знал об этом ActiveSupport, и он будет полезен для меня в других местах. –

+0

В заявлении case используется тип класса, и оператор поля привязывает значение к классу.И более того, class_attribute предоставляет вам установки уровня уровня и геттеры. –

+0

Ах да * установки уровня уровня и геттеры *. Извините, что я пропустил эту строку при чтении вашей ссылки: * Их также можно получить и переопределить на уровне экземпляра *. –

0

всегда можно определить метод, который возвращает поле, определенное в классе ребенка и назвать его в методе родительского класса.

Пример

class DocumentEtude 
    def variables 
      vars = {} 
      vars.merge!(
       "some_var" => shared_field, 
       "some_var2" => your_customized_field) 
      ... 
    end 
end 

class DocumentEtude::XXXX < DocumentEtude 
    field :only_in_xxxx_field 

    def your_customized_field 
    return only_in_xxxx_field 
    end 
end 

Конечно, это хорошая идея, чтобы позволить пользователю знать, если некоторые поля родительского класса пытается получить доступ не определены в классе ребенка, добавив это в родительском классе:

def your_customized_field 
    raise NotImplementedError, "This field is not defined yet!" 
end 

Надежда эта помощь.

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