Ruby on rails 在Rspec中重新加载ActiveRecord对象(特别是在POST请求之后)

Ruby on rails 在Rspec中重新加载ActiveRecord对象(特别是在POST请求之后),ruby-on-rails,ruby,activerecord,rspec,Ruby On Rails,Ruby,Activerecord,Rspec,我的用户模型上有一个时区属性,它跟踪用户的首选时区。默认情况下,它以nil开头 在他们的个人编辑页面上,用户可以通过从下拉列表中选择另一个时区来更改他们的时区 我的测试如下: it "updates the user's time zone on submit" do # Creates with FactoryGirl @user = create(:user) # BEFORE state confirmation expect(@user.time_zone).to be

我的
用户
模型上有一个
时区
属性,它跟踪用户的首选时区。默认情况下,它以
nil
开头

在他们的个人编辑页面上,用户可以通过从下拉列表中选择另一个时区来更改他们的时区

我的测试如下:

it "updates the user's time zone on submit" do
  # Creates with FactoryGirl
  @user = create(:user)

  # BEFORE state confirmation
  expect(@user.time_zone).to be_nil

  # Simulate the user selecting a timezone from the dropdown on their edit page. 
  # Capybara is used for selection and clicking.
  visit edit_profile_path
  select_time_zone_from_dropdown("America/New_York")

  # Submit, which sends a POST request to update the User model
  click_button("Submit")

  # AFTER state confirmation - this FAILS
  # Apparently the reload doesn't work and `time_zone` is still set to
  # nil for this user 
  @user.reload
  expect(@user.time_zone).to eq("America/New_York")
end
如您所见,测试失败是因为此用户记录的
时区从未更新

奇怪的是-

  • 在数据库中,值会正确更改。只有
    ActiveRecord
    对象没有

  • 为了绕过#1,我尝试重新加载对象属性,但没有成功

  • 如果在
    重新加载
    并手动运行
    @user.reload
    之后,我用
    binding.pry
    暂停它,它就会工作。因此,它只是在测试套件运行期间不起作用

  • 在缓存和重新加载值的过程中是否发生了一些奇怪的事情


    谢谢

    这是因为水豚使用不同的数据库连接。我有这个问题,并解决了使用这个补丁,这迫使所有线程使用相同的连接

    class ActiveRecord::Base
      mattr_accessor :shared_connection
      @@shared_connection = nil
    
      def self.connection
        @@shared_connection || retrieve_connection
      end
    end
    
    # Forces all threads to share the same connection. This works on
    # Capybara because it starts the web server in a thread.
    ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
    


    确保在您的
    spec\u helper
    文件中需要此代码

    您确定@user对象就是要更改的对象吗?“edit_profile_path”如何知道要编辑哪个用户?可能是时间问题,您是否可以添加一个
    expect(页面)。拥有('some_selector')
    ,然后
    @user。重新加载
    谢谢,这似乎是正在发生的事情。我在这里找到了更多关于它的文献——似乎仍然是个问题!我仍然困惑的是,为什么
    user.reload
    在测试中不起作用。即使水豚使用的是不同的连接,它也应该从根本上从数据库(已经正确更新)中重新提取所有信息,那么单靠这一点不就可以解决问题吗?再次感谢!(编辑:澄清一下,它确实适用于您的fix+
    用户。重新加载
    。我的意思是,我希望它在没有您的修补程序的情况下工作,对吗?@user2490003,修补程序出现之前的问题,因为在每次测试之前,rspec打开一个事务,并在最后回滚它。然后,当您在测试中调用
    user.reload
    时,事务是打开的,更改不会提交到数据库。这很有意义,再次感谢您。你帮我省了不少麻烦