2009-06-15 3 views
1

у меня есть это:Инициализация модуля вперемешку к модели

class Bullet < ActiveRecord::Base 
    include StagedVersionMethods 
    ... 
end 

И это

module StagedVersionMethods  
    def initialize 
    puts self.bullet_id 
    end 
end 

Когда я создаю экземпляр Пули, модули инициализации метод пожаров, но я получаю ActiveRecord error: ... activerecord-2.2.2/lib/active_record/attribute_methods.rb: 268: in `read_attribute '

Мое намерение - инициализировать переменную экземпляра, для которой мне нужна prima ry ключевое значение записи, в которую я вхожу. Другие методы в модуле будут работать с этой переменной экземпляра.

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

Как к этому нужно подойти?

Благодаря

ответ

0

Если определить инициализацию как:

def initialize(*atts) 
    super(*atts) 
    puts self.bullet_id 
end 

, то я думаю, что он будет делать то, что вы хотите, как он будет создан объект правильно для Вас, используя инициализацию ActiveRecord первый. Тем не менее, я не уверен, насколько надежным этот подход является то, чего вы пытаетесь достичь. Возможно, было бы более целесообразно создать эту переменную экземпляра при ее доступе, а не при инициализации объекта.

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

+0

Благодарности Shadwell, переменной экземпляры будет копией экземпляра «я», но с правками, внесенных в него. Он представляет собой временную копию «родительской» пули, и модуль будет смешивать методы с методами MOdel, такими как has_temp_version ?, apply_temp_version, discard_temp_version и т. Д. Я пробовал подход, который вы предложили (что имеет смысл), однако атрибуты self, включая bullet_id, все ноль. Я использую ваше второе предложение в настоящее время, и это работает отлично - просто немного больше сантехники, чем мне хотелось бы. Cheers – Paul

4

Переопределение инициализатора на ActiveRecord может иметь странные побочные эффекты, которые трудно отлаживать, поэтому его не рекомендуется. Рекомендуемым подходом было бы использовать обратный вызов after_initialize, который предоставляет ActiveRecord. Вы все еще можете смешать это поведение с помощью модуля ...

module MyCleverMixin 

    def after_initialize 
    puts "I'm Initializing!" 
    end 

end 


class MyModel < ActiveRecord 

    include MyCleverMixin 

end 
+0

Спасибо. Дело в том, что я ожидал, что класс станет моей моделью, в которую я смешиваю модуль, но класс класса - «класс», и блок никогда не вызывается. Я получаю неправильный конец палки? Большое спасибо. – Paul

+0

На самом деле мы можем упростить это, просто определяя after_initialize в нашем mixin. Пожалуйста, посмотрите мой отредактированный код выше для рабочего примера – user123226

+0

Должно ли быть «включать MyCleverMixin»? Следует отметить, что обратный вызов after_initialize не вызывается, когда вы нашли существующие базы данных из базы данных. Вам также нужно определить after_find. – Shadwell

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