2010-08-25 3 views
3

Я не уверен, если это даже может быть достигнуто, но здесь идет ... :)Rails - Динамически определение методов экземпляра в модели

Давайте предположим, что две модели, а Page модель и Field модель. Page has_many :fields и Field модель имеет два атрибута: :name, :value

То, что я хочу, чтобы достичь является в Page модели динамически определять методы экземпляра для каждого Field#name Возвращая Field#value.

Так что, если моя страница была поле с именем «Foobar», я бы динамически создать метод, как так:

def foobar 
    fields.find_by_name("foobar").value 
end 

это может быть достигнуто? Если да, пожалуйста, помогите?

Над к Рубистам ...

+0

сделать модели в Rails переопределить method_missing? Если нет, вы можете переопределить это самостоятельно и определить методы таким образом. – alternative

ответ

1

Вы можете переопределить method_missing для достижения своей цели:

def method_missing(method, *args, &block) 
    super 
rescue NoMethodError => e 
    field = fields.find_by_name(method) 
    raise e unless field 
    field.value 
end 

Вероятно, это лучше, чтобы добавить префикс или суффикс к вашим динамическим методам, например:

def method_missing(method, *args, &block) 
    if method.starts_with?('value_of_') 
    name = method.sub('value_of_', '') 
    field = fields.find_by_name(method) 
    field && field.value 
    else 
    super 
    end 
end 

И назовите это так:

page.value_of_foobar 
+0

Ух, поймать и переподнять, не очень хорошо. Почему бы не инвертировать заказ? Найдите поле, если оно существует, верните значение, иначе вызовите super и продолжите с отсутствующей цепочкой метода. Единственный недостаток, который я вижу с отсутствующим методом, заключается в том, что вы не могли иметь значения, названные как уже определенные методы. – Chubas

+0

Вы можете добавить префикс или суффикс к своим динамическим методам. Тогда у него не было бы такого побочного эффекта. – lest

+0

Один хороший шаблон, который вы можете использовать с отсутствующим методом: - Когда вызывается метод, динамически добавляйте этот метод к вызываемому объекту, затем вызывайте этот метод. С этого момента объект имеет метод, поэтому избегает других вызовов метода. ActiveRecord делает это, но вы обычно не меняете столбцы во время выполнения, я предполагаю, что вы измените поля во время выполнения. –

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