Skip to content

Using ratyrate with UUIDs

Nathan Flood edited this page Apr 8, 2016 · 1 revision

The problem:

If the model you are trying to apply rating to uses UUIDs instead of integers for primary keys you will experience issues. Rails will happily cast a UUID into an integer, but it does not return a globally unique integer. Ratyrate will appear to be working properly, but will not be. Your ratable objects may share these cast ids which will cause newly created objects to appear already rated, and objects will share ratings.

Our of over 1500 items in our data set, we saw that only 300 unique ids were being created, in some cases 3 to 5 different objects were sharing the same rating.

There is a simple fix:

After running the generator, but before running rake db:migrate edit all four new migrations to change the polymorphic association type to uuid.

Example:

(before)

class CreateOverallAverages < ActiveRecord::Migration 
  def self.up
    create_table :overall_averages do |t|
      t.belongs_to :rateable, :polymorphic => true
      t.float :overall_avg, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :overall_averages
  end
end

(after)

class CreateOverallAverages < ActiveRecord::Migration 
  def self.up
    create_table :overall_averages do |t|
      t.belongs_to :rateable, type: :uuid, :polymorphic => true
      t.float :overall_avg, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :overall_averages
  end
end

Note the addition of type: :uuid on this line: t.belongs_to :rateable, type: :uuid, :polymorphic => true

What files need to be changed?

  • /db/migrate/*****_create_rating_caches.rb
  • /db/migrate/*****_create_rates.rb
  • /db/migrate/*****_create_average_caches.rb
  • /db/migrate/*****_create_overall_averages.rb

Change the line above in the same way on all of the migrations then run: rake db:migrate

IMPORTANT NOTE

Ratyrate is intended to be polymorphic, making this change will limit your use of ratyrate to models that are using UUIDs. If you have a mix of integer and uuid identified models you will have to choose one or the other.