![]() Using UUIDs is a good idea in brand new projects, but it might be wise to avoid transferring to UUIDs in a running production system unless you have a good reason to do so. You can no longer assume the ‘highest’ id is the most recent, which could be confusing for new developers to your codebase. MySQL is a more complicated proposition and I wouldn’t bother.ĪctiveRecord’s first and last scopes work in an unexpected way with UUID ids. If you’re using PostgreSQL this is a straightforward change and has little performance cost. This is a case where you are making a choice toward a little more complexity, but for good reasons. You can get round this by generating ‘public ids’ or ‘slugs’ for exposed URLs… but then, why not use a built-in tool?įrom a security perspective, using UUIDs prevents the situation where a malicious attacker could attempt to gain access to data by guessing a model id in your URLs. With UUIDs no-one can guess the size of your database tables, which might be information you are keen to keep secret. With an incrementing integer id the size of your data can be inferred from the outside i.e. The UUIDs are globally unique meaning you can know that different models cannot possibly have the same id and you can even assign them client-side or in other systems. Using UUIDs as the id in your Rails models instead of incrementing integers helps you avoid collisions. references :other, type: :uuid, index: true end end end But why? If this is not feasible, the namespace variant should be used.Class AddNewTable < ActiveRecord :: Migration def change create_table :related_model do | t | t. In the end there's a small gotcha:ĭistributed applications generating UUIDs at a variety of hosts must be willing to rely on the random number source at all hosts. ![]() due to missing OpenSSL - Ruby will use the internal PRNG which at first look it appears quite solid as it uses for seeding dev/urandom but it might not be in the same class of csPRNG)įor UUIDs both implementations should yield usable random UUIDs even if the library falls back to a non csPRNG algorithm. ![]() Regarding their implementations it should be noted that they differ and if the quality of randomness is important one should further investigate (e.g. I use this method on various web sites where I typically use Postgres to generate UUIDs as primary keys for tables and pass them as ids. The only minor gripe I have with this is that there's no UUID lib for general use in Ruby supporting all the versions. It makes sense for the UUID method to be in SecureRandom in Ruby since it's only the version 4 implementation and by default it uses OpenSSL::Random. Which makes both implementations correct. The version 4 UUID is meant for generating UUIDs from truly-random or pseudo-random numbers. This started as a simple curiosity on what versions of UUID I could use - note that this is not a critique of truly-random vs PRGNs as the RFC clearly states: Interesting to note that if /dev/urandom is not available - again it falls back to PRNG - It seems there's a nuance here or even a contradiction as /dev/urandom uses csPRNG (cryptographically secure pseudorandom number generator) Conclusions Note that the use of a pseudo-random generator may compromise the uniqueness of UUIDs generated in this fashion. The uuid_generate_random function forces the use of the all-random UUID format, even if a high-quality random number generator (i.e., /dev/urandom) is not available, in which case a pseudo-random generator will be substituted. def primary_key ( name, type = :primary_key, options = Īs we can see there's a call to uuid_generate_random - what can this be? Source-code The Rails version uses uuid-ossp postgres extension: # By default, this will use the +uuid_generate_v4()+ function from the # +uuid-ossp+ extension, which MUST be enabled on your database. # It doesn't contain meaningful information such as MAC addresses, timestamps, etc. # The version 4 UUID is purely random (except the version). Param whereas Ruby's stdlib only supports version 4.Īnother interesting difference is in the implementations: In the Ruby's stdlib the UUID method is found in SecureRandom: # SecureRandom.uuid generates a random v4 UUID (Universally Unique IDentifier). This can be changed in Rails migrations via: default: 'uuid_generate_v1()' ![]() Ruby's standard library and Rails's PostgreSQL adapter use by default version 4 UUIDs.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |