在Ruby on rails应用程序中,我的ActiveRecordModel遇到了一个奇怪的行为.每次我访问该模型时,它似乎都返回相同的对象实例.我不确定这是标准行为还是我的实现的潜在问题.

情况是这样的:

我有一个继承自ApplicationRecordMyModel类.在这个类中,我定义了两个类方法:testtest2.test方法基于特定条件过滤MyModel条记录,然后调用test2.test2方法遍历集合,更新每条记录,然后try 按其ID查找相同的记录.

class MyModel < ApplicationRecord
  def self.test
    MyModel.where(some_column: "A").test2
  end

  def self.test2
    all.each do |my_model|
      my_model.update(some_column: "B")
      MyModel.find(my_model.id)
    end
  end
end

然而,在这个过程中,我遇到了一个ActiveRecord::RecordNotFound例外,这似乎不寻常.例外消息为:

ActiveRecord::RecordNotFound (Couldn't find MyModel with 'id'='the_id_of_record' [WHERE "my_models"."some_column" = $1])

该错误表明,在更新记录后,后续的find操作无法找到该记录.我正在try 理解这是由于某种ActiveRecord缓存机制还是我方法中的缺陷造成的预期行为.此外,对于如何有效地处理这种情况,如果有任何见解或建议,我将非常感激.

推荐答案

此行为是故意的.您正在关系上调用test2个方法,这意味着它充当一个作用域,而不仅仅是一个方法调用:

100

>> puts MyModel.where(some_column: "A").method(:test2).source
def #{method}(...)
  scoping { klass.#{method}(...) }
end

注意,方法调用通过scoping方法委托给MyModel.test2.

将所有查询的范围限定为当前范围.

Comment.where(post_id: 1).scoping do
  Comment.first
end
# SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 ORDER BY "comments"."id" ASC LIMIT 1

100

class MyModel < ApplicationRecord
  def self.test
    MyModel.where(some_column: "A").test2
  end

  def self.test2
    all.each do |my_model|
      my_model.update(some_column: "B")

      # NOTE: when you do this, `current_scope` is taken into account
      #       which you can take a look at:
      p "current_scope"
      p current_scope.to_sql
      MyModel.find(my_model.id)
    end
  end
end
#=>
# "current_scope"
# "SELECT \"my_models\".* FROM \"my_models\" WHERE \"my_models\".\"some_column\" = 'A'"

你可以用MyModel.unscoped.find(my_model.id),但我不明白你为什么要这么做.此外,您也不能将方法调用链接到关系:

class MyModel < ApplicationRecord
  def self.test
    MyModel.where(some_column: "A")
  end

  def self.test2 q
    q.each do |my_model|
      my_model.update(some_column: "B")
      MyModel.find(my_model.id)
    end
  end
end

>> MyModel.test2(MyModel.test)

Ruby-on-rails相关问答推荐

rails中Net::STP的多文件模式

尽管安装并需要 pry-rails gem,但 Rails 容器内出现未定义方法‘pry’错误

为什么 2 个关键字参数被解释为 1?

Rails 使用多个外键创建/构建

has_many 通过大小验证

在 Datatable Ajax 调用中通过 Ajax 更新 div

Rspec期望()与期望{}

在bash中匹配带有空格字符的字符串

如何避免 activesupport 中的循环参数引用警告

为 ActionMailer 渲染不同的视图(模板)

如何判断是否已经在 ruby​​ on rails 的数据库事务中?

如何将 Ruby 哈希转换为 XML?

Rails 和 OS X:如何安装 rmagick?

RSpec > 有没有办法用一个命令运行所有测试?

带有查询字符串参数的 Rails 动作缓存

使用 ruby​​ on rails 活动记录插入多条记录

活动管理员:仅自定义新表单

如何从 rails 控制器操作发出 404 响应?

Ruby:如何将一种方法接收到的所有参数和块传递给另一种方法?

Rails:为什么 with_exclusive_scope 受保护?关于如何使用它的任何好的做法?