D
D
Demigodd2020-06-12 16:46:26
Ruby on Rails
Demigodd, 2020-06-12 16:46:26

Why does the variable in the model change?

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']


When changing book_types for the first book, the variable remains changed for the second.
Why is this happening and what is happening at the program level?

I need this global type in the model, but how can I make it not changeable for different books.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Z
Zaporozhchenko Oleg, 2020-06-12
@Demigodd

Because when creating an object, ruby ​​does not copy the data of the class, but stores a reference to it. TYPES is a class constant, when it changes, the data will be updated for all objects. In the case of an ordinary class, you would need to override the initialize method with the required variable set, but for a model it is not desirable to do this and it is better to use a callback.
In addition, the assignment works by reference, so the array needs to be copied

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

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question