Ruby Mixin 模块不保存 Active Record 属性

Ruby Mixin module not saving Active Record property

我有一个电子书资源,其值为 属性:

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

但它不会更新或保存模型。

A​​ctiveRecord 不为数据库中表示的属性使用单独的实例变量。

将您的方法更改为

def change_value
  self.value = 200
end

为了使用 ActiveRecord 为您的模型生成的 setter 方法。

为了更清楚一点,你的代码是这样做的:

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