Модуль Ruby Mixin не сохраняет свойство Active Record - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть ресурс eBook со свойством value:

class EBook < ApplicationRecord
  include Mixin
end

и модулем:

module Mixin
  extend ActiveSupport::Concern
  included do
    # validations
    belongs_to :user
  end
  def change_value
    @value = 200
  end
end

Я хотел бы иметь возможность вызвать EBook.change_value и иметь этот экземплярзначение установлено на 200.Как я могу это сделать?Это антипаттерн?Кажется, я не могу найти ничего, что позволило бы мне изменять состояние экземпляра через модуль.

Используя консоль rails, я получаю такой вывод:

  EBook Load (0.3ms)  SELECT  `e_books`.* FROM `e_books` ORDER BY `e_books`.`id` ASC LIMIT 1 OFFSET 1
 => 200

, но он не обновляетсяили сохраните модель.

1 Ответ

0 голосов
/ 28 сентября 2018

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

Измените ваш метод на

def change_value
  self.value = 200
end

, чтобы использовать метод сеттера, сгенерированный ActiveRecord для вашей модели.

Чтобы прояснить это немного, ваш код сделал следующее:

class Ebook < ApplicationRecord
  attr_reader :value

  def change_value
    @value = 200
  end
end

2.5.1 :001 > e = Ebook.new
 => #<Ebook id: nil, value: nil> 
2.5.1 :002 > e.change_value      # this sets your instance_variable
 => 200 
2.5.1 :003 > e
 => #<Ebook id: nil, value: nil> # ActiveRecord's value remain nil
2.5.1 :004 > e.value             # reads from instance variable as we've overwritten the method with attr_reader
 => 200 
2.5.1 :005 > e.read_attribute(:value) # reads from ActiveRecord's attributes
 => nil 
2.5.1 :006 > e.tap(&:save)
 => #<Ebook id: 3, value: nil>   # as expected, nothing is saved
...