【问题标题】:How can I force the rails SQL cache to clear?如何强制清除 Rails SQL 缓存?
【发布时间】:2015-05-19 18:36:38
【问题描述】:

我在我的测试脚本(直接导入并与模型交互)中的测试之间运行rails db:reset db:migrate,但更改未反映在第一个测试和第二个测试之间。更具体地说,第一次测试引起的变化并没有按原样逆转。

当我从外部(从 shell)连接到数据库时,我观察到命令已经生效。

我已经看过this question,但解决方案没有效果(从字面上看,没有错误,但也没有明显的效果)。

如何强制我的测试脚本清除其内存缓存中的 sqlite 状态?


重现问题的完整步骤。

  1. 创建一个新的 Rails 应用程序。

    rails new MWE
    
  2. 将以下内容放入db/schema.rb

    ActiveRecord::Schema.define(version: 20140408213603) do
        create_table "users", force: true do |t|
        t.string   "username"
      end
    end
    
  3. 将以下内容放入db/seed.rb

    User.create(username: 'user1')
    User.create(username: 'user2')
    User.create(username: 'user3')
    
  4. 将以下内容放入Gemfile

    source 'https://rubygems.org' 
    gem 'rails', '4.0.0' 
    gem 'sqlite3' 
    gem 'protected_attributes' 
    
  5. 将以下内容放入名为 app/models/user.rb 的文件中。

    class User < ActiveRecord::Base
      attr_accessible :username
    end
    
  6. 运行以下命令。

    bundle install
    rake db:reset
    
  7. 将以下内容放入名为MWE.rb的文件中

    load 'config/application.rb'
    load 'config/environment.rb'
    load 'app/models/user.rb'
    
    # Mimic the unsafe call in the source code
    system("bundle exec rake db:reset")
    puts User.count
    User.destroy_all("username = 'user3'")
    puts User.count
    system("bundle exec rake db:reset")
    puts User.count
    User.destroy_all("username = 'user3'")
    puts User.count
    
  8. 运行文件并观察实际输出

    $ ruby MWE.rb
    -- create_table("users", {:force=>true})
       -> 0.0362s
    -- initialize_schema_migrations_table()
       -> 0.0248s
    3
    2
    -- create_table("users", {:force=>true})
       -> 0.0809s
    -- initialize_schema_migrations_table()
       -> 0.0490s
    2
    2
    

所需的输出

    -- create_table("users", {:force=>true})
       -> 0.0362s
    -- initialize_schema_migrations_table()
       -> 0.0248s
    3
    2
    -- create_table("users", {:force=>true})
       -> 0.0809s
    -- initialize_schema_migrations_table()
       -> 0.0490s
    3
    2

如何强制数据库重置反映在模型中?

【问题讨论】:

  • 您能否发布一些代码以便我们重现该问题?
  • @BroiSatse,我正在努力。为此创建一个 MWE 并非易事,所以我想我会在完成 MWE 之前发布,以防有​​人已经看到这个问题。
  • @BroiSatse,已发布完整的 MWE。请注意,我是 ruby​​ / rails 的相对新手,所以如果您知道如何使这个 MWE 变得更小,也请对此发表评论。

标签: ruby-on-rails ruby caching


【解决方案1】:

您需要做的就是重新建立数据库连接。试试:

system("bundle exec rake db:reset")
puts User.count
User.destroy_all("username = 'user3'")
puts User.count

system("bundle exec rake db:reset")
ActiveRecord::Base.clear_all_connections!
puts User.count
User.destroy_all("username = 'user3'")
puts User.count

主要问题是:为什么需要这样做?我很确定有更好的方法来实现你想要的。

【讨论】:

  • 我正在为我正在教授的课程编写一个自动评分器。要评分的作业之一是 SQL 注入,由于这种注入有多种错误编写方式,我想在运行不同学生的提交之间重置我的数据库状态。
  • @merlin2011 - 听起来很酷。 :) 所以他们会在网站上写一些代码,你想把它作为迁移运行吗?
  • 是的,这就是一般的想法。不幸的是,项目的某些部分依赖于 Ruby,而 Ruby 并不是我的母语。 :P
  • 嗯,我仍然收到 undefined method clear_all_connections!'` 即使在 Gemfile 中有 gem activerecord
  • 感谢您的帮助!
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 2017-03-15
  • 2021-09-03
  • 2023-03-31
  • 1970-01-01
  • 2011-05-02
  • 2016-02-18
相关资源
最近更新 更多