module RandomUniqueId::ClassMethods
Collection of methods that will end as class methods of ActiveRecord::Base.
@see ActiveSupport::Concern
Public Instance Methods
Augment the ActiveRecord belongs_to
to also define rid accessors. For example: if you blog post belongs_to
an author, on top of the methods author, author=, author_id and author_id=, it’ll also have author_rid and author_rid= that allow you to retrieve the RID of the author or set another author by using the RID.
@param attrs [Array] same as the parameters for ActiveRecord::Associations::ClassMethods.belongs_to except that
passing rid: false will prevent the rid accessors from beign defined.
@see ActiveRecord::Associations::ClassMethods.belongs_to
# File lib/random_unique_id.rb, line 66 def belongs_to(*attrs) define_rid_method = attrs[1].try(:delete, :rid) super.tap do if define_rid_method != false relationship_name = attrs[0] rel = reflections[relationship_name] || reflections[relationship_name.to_s] return if rel.options[:polymorphic] # If we don't know the class, we cannot find the record by rid. class_name = rel.options[:class_name] || relationship_name.to_s.classify related_class = class_name.constantize define_rid_accessors(related_class, relationship_name) if related_class.attribute_names.include? "rid" end end end
Mark a model as containing a random unique id. A field called rid of type string is required. It’s recommended that it’s indexed and unique. For example, you could add it to a migration like this:
def up add_column :posts, :rid, :string add_index :posts, :rid, :unique end
and then to the model like this:
class Post has_random_unique_id # ... other stuff end
@param options [Hash] generation options, same as RandomUniqueID.config, in case the generation method or minimum
length needs to be overridden for one specific model
# File lib/random_unique_id.rb, line 52 def has_random_unique_id(options={}) options = RandomUniqueId.config.merge(options) before_validation :populate_rid_field, if: Proc.new { |r| r.send(options[:field]).blank? } add_rid_related_validations(options) add_rid_related_methods(options) end
Populate all the blank rids in a table. This is useful when adding rids to a table that already has data in it. For example:
def up add_column :posts, :rid, :string add_index :posts, :rid, :unique say_with_time "Post.populate_random_unique_ids" do Post.reset_column_information Post.populate_random_unique_ids { print "."} end end
This method uses update_column to avoid running validations and callbacks. It will not change existing rids, so it’s safe to call several times and a failure (even without a transaction) is not catastrophic.
# File lib/random_unique_id.rb, line 95 def populate_random_unique_ids find_each do |record| rid_just_populated = false if record.send(record.random_unique_id_options[:field]).blank? record.populate_rid_field record.update_column(record.random_unique_id_options[:field], record.send(record.random_unique_id_options[:field])) rid_just_populated = true end yield(record, rid_just_populated) if block_given? end end
Private Instance Methods
Defines the setter and getter for the RID of a relationship.
@param related_class [Class] class in which the RID methods are going to be defined. @param relationship_name [String] name of the relationship for which the RID methods are going to be defined. @see RandomUniqueId::ClassMethods.belongs_to
# File lib/random_unique_id.rb, line 128 def define_rid_accessors(related_class, relationship_name) define_method("#{relationship_name}_rid") do self.send(relationship_name).try(random_unique_id_options[:field]) end define_method("#{relationship_name}_rid=") do |rid| record = related_class.find_by_rid(rid) self.send("#{relationship_name}=", record) record end end