Ruby Mixin模块未保存活动记录属性

时间:2018-09-28 02:27:14

标签: ruby-on-rails ruby module mixins

我有一个具有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 :(得分:3)

ActiveRecord不会对数据库中表示的属性使用单独的实例变量。

将方法更改为

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