Перезаписать все стандартные методы доступа в модели рельсов - PullRequest
0 голосов
/ 03 ноября 2010
 class Song < ActiveRecord::Base
    # Uses an integer of seconds to hold the length of the song

    def length=(minutes)
      write_attribute(:length, minutes.to_i * 60)
    end

    def length
      read_attribute(:length) / 60
    end
  end

Это простой пример rails api doc.

Возможно ли перезаписать все атрибуты для модели без перезаписи каждого из них?

Ответы [ 2 ]

0 голосов
/ 03 ноября 2010

Я не уверен в случае использования, где это было бы хорошей идеей. Однако всем моделям рельсов динамически присваиваются их свойства (при условии, что их еще нет в классе). Ответ частично на ваш вопрос.

Вы можете переопределить методы read_attribute () и write_attribute (). Это применило бы ваши преобразования к каждому атрибуту, независимо от того, были ли они записаны средством доступа или заполнены массово в контроллере. Только будьте осторожны, чтобы не изменять такие важные атрибуты, как атрибут 'id'.

У Ruby есть ярлык, который используется в коде рельсов, и он может вам помочь. Это ключевое слово% w. % w создаст массив слов на основе символов внутри скобок. Поскольку это массив, вы можете делать такие полезные вещи, как это:

@excludes = %w(id, name)

def read_attribute name
    value = super
    if(not @excludes.member? name)
        value = value.to_i * 60
    end

    value
end

def write_attribute name, value
    if(not @excludes.member? name)
        value = value.to_i / 60
    end

    super
end

Это должно начать вас. Существуют более продвинутые конструкции, такие как использование лямбды и т. Д. Имейте в виду, что вам следует написать несколько тщательных модульных тестов, чтобы убедиться, что у вас нет непредвиденных последствий. Возможно, вам придется включить больше имен атрибутов в список исключений.

edit: (чтение | запись) _attributes -> (чтение | запись) _attribute

0 голосов
/ 03 ноября 2010

Ты ищешь что-то подобное?Не знаю, почему вы хотели бы сделать это, но здесь вы идете:)

class Song < ActiveRecord::Base

  self.columns_hash.keys.each do |name|
    define_method :"#{name}=" do
      # set
    end

    define_method :"#{name}" do
      # get
    end

    # OR

    class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
       def #{name}=
         # set
       end

       def #{name}
         # get
       end
    METHOD

  end

end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...