Rails: добавление методов к activerecord (правильный путь?) - PullRequest
0 голосов
/ 30 марта 2012

Я возился с созданием рельса и у меня возникают проблемы с добавлением методов в ActiveRecord. Допустим, я хочу сделать следующее:

class DemoModel < ActiveRecord::Base
  custom_method :first_argument, :second_argument
end

Чтобы сделать это, я добавляю следующее:

module DemoMethod

  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods       
    def custom_method(*fields)
      @my_fields = fields
    end
  end

end

ActiveRecord::Base.send(:include, DemoMethod)

Пока все хорошо.

Проблема в том, что я хочу получить доступ к этой переменной my_fields из экземпляра модели. Например, я мог бы открыть form_for что-то вроде:

module ActionView::Helpers::FormHelper
  def fields_for(record_name, record_object, options = {}, &block)
    the_fields = record_object.<I WANNA ACCESS @my_fields HERE!!!>.html_safe
    # ...
  end
end

Сложность в том, что «custom_method», по-видимому, работает, только если я установил помощника как метод класса, но это означает, что .self теперь является Model (DemoModel) вместо объекта DemoModel, над которым я хочу работать. Я мог бы передать объект вручную с помощью «custom_method self,: first_argument,: second_argument», но кажется немного неуклюжим попросить пользователей моего замечательного самоцвета «custom_method» добавить «self» к их списку аргументов.

Итак, вопрос в том, как бы более мудрый Rails установил значения для определенного объекта через custom_method, а затем получил их где-то еще, например fields_for?

Как всегда, любые предложения приветствуются.

1 Ответ

2 голосов
/ 30 марта 2012

Использование self.included и ClassMethods добавляет методы как методы класса.

Определение методов в модуле, а затем их включение - это способ создания обычных методов экземпляра. Вот так:

module DemoMethod

   def custom_method(*fields)
    @my_fields = fields
  end
end

ActiveRecord::Base.send(:include, DemoMethod)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...