Where Does Rails Store Data Created by Saving Activerecord Objects During Tests

Where does Rails store data created by saving activerecord objects during tests?

Items in the test database are erased by default after each test is run, by design. This is done to make sure that each of your tests has its own sandbox to play in that doesn't cause any interactions with the tests before it.

Again, this is by design. You don't want tests that are manipulating the same set of data (or rely on synchronous execution), because there is no guarantee of execution order.

However, I believe if you modify you test/test_helper.rb file to say this:

self.use_transactional_fixtures = false

instead of

self.use_transactional_fixtures = true

It will cause the data in your test database to persist.

ALSO: My advice is specifically designed to work with Test::Unit, not RSpec. However, I imagine that there is a similar setting your spec_helper.rb you should be looking for.

Rails test data, in the database

In most cases, I agree with @mrbrdo's opinion: prefer rpsec's stub method. but as a rails programmer, I think you have to know both the "fixture" and the "stub".

Fixtures, whatever the yaml file or the factory girl data , will both save into database. see your config/database.yml file for the location where they are. Actually this is useful when you want to make sure that there is ALWAYS some data in the DB during your test, such as an "admin user" with a fixed ID.

Stubs, it's faster than fixture since it won't be saved into DB, and maybe very useful when you want to perform a test that can't implemented by "Fixtures".

So, I suggest that you try both of them in your real coding life, and choose either of them according to the real context.

Rails ActiveRecord object not saving

  1. .save returns true or false. .save! raises errors. If you need to know why something is going wrong with a (somewhat) detailed message, use .save!.

  2. If key is not unique, the data will not be saved because the model will not pass validation. Try running Model.where(:key => 'test').destroy_all and reevaluate.

How to have factory only create data one time for all tests in Rspec

If multiple copies of test objects are persisting between tests this creates huge problems for your tests, and they cannot be relied on.

You have to have a clean slate between tests. There are a number of ways to do this, but it can get complicated with factories, fixtures, transactional fixtures, etc.

I personally almost always end up using a database cleaner.

Have a look at Database Cleaner

Rspec tests failing randomly when analysing ActiveRecord objects generated by Mongoid events

In a typical Mongodb setup, there can be a delay between when a database write returns successfully and when that data can be read. There are two reasons for this:

  • For performance gains, an "unsafe" write can return before the data is committed to the disk.
  • Mongodb uses replica sets and there is a replication delay. Commonly reads are distributed to the replicas as a form of load balancing, so even if you use a safe write, you may be reading from a different server than the one you just wrote to and thus not see the data you just wrote.

To ensure that you can always immediately read back the data you just wrote using Mongoid, you need to set the database session options consistency: :strong, safe: true, neither of which are the default.

RSpec: check if any model has been saved

Not sure if Rspec could help you with this, but a quick manual trip to the database might do the job?

[Model1, Model2].each do |model|
model.where('updated_at > ?', Time.now - 2.seconds).count.should eq 0
end

With activerecord how can I stop memory thrashing

I'd hate to say no, but there's no way to do that and keep following the Active Record pattern, which is a principle under the hood of Rails' ActiveRecord. As the Wikipedia article states:

an object instance is tied to a single row in the table

From that you can tell, that you cannot map a single object to multiple distinct rows.

Rails' ActiveRecord objects come in two different forms that look alike but work differently inside:

  • Not persisted objects (results of new, association.build and maybe some others)

    They don't have ids yet, they're not yet valid "Active Records", that implies that on save a new row in the database is created and the object is considered persisted from that moment.
  • Persisted objects (received from the database in any way)

    An object considered a valid row in the database without most implications. Any operation with that object should be reasonable in context of a RDBMS.

That said, to do that, you'd have to dive into the depths of AR implementation, because to "unpersist" an AR object (if you follow the pattern) you have to remove it from the database. No exceptions in current AR's implementation.

Here's a little experiment. Once we have an unpersisted object, we can examine it and find out it has an id equal to nil. Now let's get a persisted object and do this:

# assume we did `t = Thing.first` before
t.id = nil
t.save!

Create a new object? No! Update existing one!

UPDATE `things` SET `id` = NULL WHERE `things`.`id` = 1

Of course, DB rejects this query because it's not reasonable in terms of RDBMS to set primary key of any record to NULL:

Column 'id' cannot be null

Why? See this question. Briefly, that's because NULL != NULL



Related Topics



Leave a reply



Submit