Demigodd
@Demigodd

Почему переменная в моделе меняется?

class Book < ActiveRecord::Base
  TYPES = ['Classics', 'Fantasy']

  def book_types
    TYPES
  end
end

first_book = Book.first
last_book = Book.last

first_book.book_types << 'NEW'

first_book.book_types # ['Classics', 'Fantasy', 'NEW']
last_book.book_types # ['Classics', 'Fantasy', 'NEW']


При изменений book_types для первой книги, переменная остаеться изменной и для второй.
Почему так происходит и что вообще происходит на программном уровне ?

Мне нужен этот глобальный тип в моделе, но как его сделать не изменными для разных книг.
  • Вопрос задан
  • 76 просмотров
Решения вопроса 2
c3gdlk
@c3gdlk
Ментор в http://rubyboost.ru/
Потому что руби при создании объекта не копирует данные класса, а хранит ссылку на него. TYPES это константа класса, при ее изменении данные обновятся у всех объектов. В случае обычного класса Вам нужно было бы переопределить метод initialize с установкой нужной переменной, но для модели это делать не жлательно и лучше воспользоваться колбеком.

Кроме того присваивание работает по ссылке, поэтому массив нужно именно скопировать

class Book < ActiveRecord::Base
  DEFAULT_TYPES = ['Classics', 'Fantasy']

  after_initialize :set_default_book_types

  def book_types
    @book_types
  end

  def set_default_book_types
    @book_types = DEFAULT_TYPES.map(&:clone)
  end
end
Ответ написан
Комментировать
amerov
@amerov
Web Developer
def book_types
  TYPES # тут TYPES передается по ссылке
end


возможно, вам подойдет вариант с дублированием:
def book_types
  TYPES.dup
end
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы