在 after_create 中调用时 update_attribute 会被忽略吗?

is update_attribute ignored when called in after_create?

我有一个称为过滤器的 Activerecord 模型,过滤器可以通过我称之为 'filterabe'

的多态关系应用于多个对象

我有另一个对象称为 AssignmentRule,在本例中它主要是过滤器的集合。

分配规则有一个 after_create,看起来像这样:

class AssignmentRule < ApplicationRecord
  has_many :filters, as: :filterable, dependent: :destroy
  after_create :add_scope_filters
        
  def add_scope_filters
    if initial_scope_type
      if initial_scope_type == 'staff'
        filter = Filter.new
        filter.filter_type = 'all_bosses'
        filter.user_id = creator_id
        filter.course_id = self.course_id
        filter.value = '["'+creator_id.to_s+'"]'
        filter.view_type = 'AssignmentRule'
        filter.locked = true
        self.filters << filter
        initial_scope_type = nil
        save
      else

      end
      #update_attribute(:initial_scope_type, nil)
    end
  end

end

因为分配规则经常被欺骗,所以我不希望这条规则只针对原始规则而被欺骗。因此将使用带有字符串值的 initial_scope_type 创建原件。规则触发后,我不想保留字符串值,所以我将其设置为 nil 并保存。

问题是没有保存???

我在保存调用上放置了一个调试器,并进行了终端交互:

>initial_scope_type = nil
nil
>initial_scope_type
nil
>save
  SQL (1.1ms)  UPDATE `assignment_rules` SET `id` = 144, `course_id` = 195, `creator_id` = 18279, `created_at` = '2020-07-24 11:00:24', `updated_at` = '2020-07-24 11:00:24', `edits_assignment_rule_id` = 128, `editor_id` = 18279, `initial_scope_type` = 'staff' WHERE `assignment_rules`.`id` = 144
true
>wtf
undefined local variable or method `wtf' for #<AssignmentRule:0x00007f9b3b55a608>

我尝试过的事情:

改为调用 update_attribute(参见代码中的注释), 添加自我。我的 initial_scope_type 是这样的:self.initial_scope_type = nil

行为保持不变....我很困惑,这是一个简单的赋值,为什么它不起作用?

提前感谢您的回答!

我在 rails 5.0.7.2 和 mysql 8.0.18

上使用 ruby 2.6.5

更新:

用 self 调用 initial_scope_type 的结果似乎略有不同,但结果是一样的:

>self.initial_scope_type
"staff"
>self.initial_scope_type = nil
nil
>self.initial_scope_type
nil
>self
#<AssignmentRule id: 149, course_id: 195, creator_id: 18279, created_at: "2020-07-24 17:06:02", updated_at: "2020-07-24 17:06:02", edits_assignment_rule_id: 148, editor_id: 18279, initial_scope_type: nil>
>self.save
  SQL (2.5ms)  UPDATE `assignment_rules` SET `id` = 149, `course_id` = 195, `creator_id` = 18279, `created_at` = '2020-07-24 13:06:02', `updated_at` = '2020-07-24 13:06:02', `edits_assignment_rule_id` = 148, `editor_id` = 18279 WHERE `assignment_rules`.`id` = 149
true

当 self 被调用时 sql 在保存时略有不同,而不是像上面的例子那样故意将 initial_scope_type 设置为 staff ,它一起被省略了。我是不是遗漏了什么,我需要打个特别的电话把它设置为空吗?

补充更新:这次我用数据库调用结束了我的调试。

>AssignmentRule.find(self.id)
  AssignmentRule Load (0.8ms)  SELECT  `assignment_rules`.* FROM `assignment_rules` WHERE `assignment_rules`.`id` = 151 LIMIT 1
#<AssignmentRule id: 151, course_id: 195, creator_id: 18279, created_at: "2020-07-24 17:43:54", updated_at: "2020-07-24 17:43:54", edits_assignment_rule_id: 150, editor_id: 18279, initial_scope_type: "staff">
>self.initial_scope_type
"staff"
>self.initial_scope_type = nil
nil
>self.initial_scope_type
nil
>self
#<AssignmentRule id: 151, course_id: 195, creator_id: 18279, created_at: "2020-07-24 17:43:54", updated_at: "2020-07-24 17:43:54", edits_assignment_rule_id: 150, editor_id: 18279, initial_scope_type: nil>
>self.save
  SQL (0.9ms)  UPDATE `assignment_rules` SET `id` = 151, `course_id` = 195, `creator_id` = 18279, `created_at` = '2020-07-24 13:43:54', `updated_at` = '2020-07-24 13:43:54', `edits_assignment_rule_id` = 150, `editor_id` = 18279 WHERE `assignment_rules`.`id` = 151
true
>AssignmentRule.find(self.id)
  AssignmentRule Load (0.7ms)  SELECT  `assignment_rules`.* FROM `assignment_rules` WHERE `assignment_rules`.`id` = 151 LIMIT 1
#<AssignmentRule id: 151, course_id: 195, creator_id: 18279, created_at: "2020-07-24 17:43:54", updated_at: "2020-07-24 17:43:54", edits_assignment_rule_id: 150, editor_id: 18279, initial_scope_type: "staff">

这是 Rails 5.0 中的错误。我更新到 Rails 5.1,一切开始按预期运行。