1

I'm pretty new to Rails and was reading some resources on the subject. And I got some questions on it. Ok, let's say we do have a model, that validates some attribute uniqueness:

class User < ActiveRecord::Base
  attr_accesible :name
  validates :name, uniqueness: true
end

So, I reasonably expect now, that I will not be able to create (or to be more precise -- save) two User instances with the same name into the database. However, this resource does insist, that it is still possible!

  • Some user signs in.
  • Clicks 'Sign in' button more than one time
  • Request 1 creates user in memory (valid)
  • Request 2 creates user in memory (valid)
  • Request 1 is successfully saved
  • Request 2 is successfully saved

And later on this source advises to add index in database to the 'name' column and make it unique.

But, if as I said it before -- validation takes place upon save procedure, then how is it possible for the 2nd request to be saved? Or I've lost something?

(the resource I was mentioning is Rails Tutorial

3
  • 1
    This happens only in large scale system. When traffic is high response of first request will be delayed. So 2nd request model validation will pass. And both will save in database. And you can't produce it in local machine. I mean in development mode. If you want see it practically your app should have high traffic. This also happens when you scale your app to get request on different boxes( I mean load balancing). When user double clicks request might go to different node. And both will pass the validation at same time and got save in db. Commented Feb 18, 2013 at 18:19
  • Or you can put it to sleep during a second or two during validation or before_save just to see the result. :) Commented Feb 18, 2013 at 18:23
  • Hmm but what about the transactions? If I got you correct, the problem is in that DB itself does not respond for a quite long time and it's possible to make another request with the same name? But I thought it is not possible, until the first request is done. Commented Feb 18, 2013 at 18:28

1 Answer 1

3

The second request is fired before the first record is saved in DB, so rails verifies that there isn't a record with the name specified an allows it to save. That's why it is recommended to add an unique to the database field, to avoid these edge cases.

Or in other words, the records passes the validations in memory.

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm, then I still don't get it. I 'fired-up' my rails console, created two users with the same names, and it was ok, until I called save on the first one. Then I repeated the operation, created 3 users, one was already on db, two in memory. And it still was ok. So, what I'm trying to say -- that validation is not happening in memory, but on save to db only.
Try this: u = User.create(name: "test") and them u2 = User.new(name: "test"), them u2.valid? should be false.
Yep, it is indeed. So, as a solution to my question I see: When the first user was created and the second one -- the was not such a record in DB, so valid? (that actually calls SELECT bla-bla from DB) is true for both. After that I save user1, and than user2. But, valid? for user2 is returned as true again, because of the high latency of overloaded DB, that can't serve correctly user2.valid? (in time)?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.