2014-05-30 4 views
4

Я хочу переписать getter store_accessor. Который может быть найден here. Код здесь:Понимание «attribute_will_change!» метод

# File activerecord/lib/active_record/store.rb, line 74 
     def store_accessor(store_attribute, *keys) 
     keys = keys.flatten 

     _store_accessors_module.module_eval do 
      keys.each do |key| 
      define_method("#{key}=") do |value| 
       write_store_attribute(store_attribute, key, value) 
      end 

      define_method(key) do 
       read_store_attribute(store_attribute, key) 
      end 
      end 
     end 

     self.stored_attributes[store_attribute] ||= [] 
     self.stored_attributes[store_attribute] |= keys 
     end 

Я достиг функциональности я был после того, как, впрочем, если бы я также перезаписать сеттер, есть метод, который мне не ясно, что находится в пределах write_store_attribute(...) метода (найденного here).

Код здесь:

# File activerecord/lib/active_record/store.rb, line 108 
     def write_store_attribute(store_attribute, key, value) 
     attribute = initialize_store_attribute(store_attribute) 
     if value != attribute[key] 
      send :"#{store_attribute}_will_change!" 
      attribute[key] = value 
     end 
     end 

Метод, который я не понимаю "#{whatever_store_att}_will_change!".

Если я должен был перезаписать установщика, я бы использовал update_attributes или update_column. Этот метод делает назначение attribute[key]=value действительно модифицировать поле в БД, что эквивалентно update_attributes?

ответ

8

Это часть системы отслеживания изменений activemodel, в которой используется активная запись, чтобы знать, что ей нужно написать в db (если есть).

Когда вы вызываете сохранение записи, тогда activerecord создает запрос обновления для всех атрибутов, которые он считает измененными (и если нет измененных атрибутов, то он ничего не делает).

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

Это именно то, что происходит здесь: когда вы устанавливаете ключ для сохраненного атрибута - рельсы изменяют хеш (в отличие от назначения нового хэша), и поэтому для поддержания отслеживания изменений необходимо позвонить _will_change! базовому атрибуту потребуется запись в db в следующий раз, когда будет вызываться save.

+0

спасибо! большое объяснение. Несколько вопросов: 1) Просмотр одного и того же файла для * Rails 3.2.13 * вместо * Rails 4.x *, я вижу, что вызов '_will_change!' Выполняется * после * атрибута присваивания [key ] = значение', в отличие от * Rails 4 *. Я полагаю, это не имеет значения ?. 2) Я предполагаю, что этот столбец «Hstore» не имеет значения, не так ли? Поскольку в ранних версиях Rails не было возможности создавать аксессоры для столбцов 'hstore'. Или, может, я ошибаюсь? – lllllll

+0

Это не должно иметь значения. Я не думаю, что материал hstore имеет большое значение - он не так сильно отличается от сериализованных столбцов, которые всегда имели, кроме (принципиально) базы данных, понимающих сериализацию –

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