Search code examples
ruby-on-railsrubyvirtus

what a method 'books=(books)' is doing?


I joined Rails team and maintain the codes. Some of the objects are controlled by Gem virtus, but I really don't understand like below code is doing.

I understand the result that the attribute 'latest_book' can collect latest book from Books but why it can be done? What 'books=(books)' is doing? and Why 'super books' is here?

class GetBooks
  include Virtus.model
  include ActiveModel::Model

  attribute :books, Array[Book]
  attribute :latest_book, Book

  def books=(books)
    self.latest_book = books.sort_by { |book| book['createdate'] }.last
    super books
  end
end

Could you help me?


Solution

  • def books=(books) is defining a method called books= which takes a single argument books. Yes, that's confusing. It should probably be def books=(value) or def books=(new_books).

    And yes, the = is part of the method name. self.books = value is really syntax sugar for self.books=(value). Again, the method is books=.

    super books is super(books). super calls the next inherited or included method of the same name; it's calling books= created by attribute :books, Array[Book]. This is a "method override" which allows you to add to the behavior of an existing method.

    When books= is called it updates latest_books and then calls its the original method to set the books attribute.

    gb = GetBooks.new
    gb.books = [old_book, new_book]
    
    p gb.latest_book # new_book
    p gb.books       # [old_book, new_book]