Skip to content

Instantly share code, notes, and snippets.

@JeffCohen
Created September 2, 2015 04:07
Show Gist options
  • Save JeffCohen/4e0544f2e6c128134b71 to your computer and use it in GitHub Desktop.
Save JeffCohen/4e0544f2e6c128134b71 to your computer and use it in GitHub Desktop.
Crazy initializer - good for one-off Rails apps
# Add this file to your config/initializers directory.
#
# Then you can do things like:
#
# Product[5] instead of Product.find_by(id: 5)
# Product.sample to pull a random Product row
# Product.sample(3) to pull three random Product rows (but they will be consecutive)
#
# Biggest part: automatic associations!
#
# Normal belongs_to/has_many will "just work" based on foreign key detection.
# You will need to add any has_many :through associations yourself.
#
# Finally, the stupid "You must establish a connection" in Rails console has been silenced.
class ActiveRecord::Base
def self.sample(n = 1)
n = [[n.to_i, 1].max, count].min # guard against invalid sample size
offset(rand(count - n)).first(n)
end
def self.[](id)
find_by_id(id)
end
end
module EZ
class AssociationInjector
def models
@models ||= begin
tables = ActiveRecord::Base.connection.tables - ["schema_migrations"]
models = tables.map { |t| t.classify.constantize }
end
end
def inject_associations
models.each do |model|
inject_association_for model
end
end
def inject_association_for(model)
model.column_names.grep(/_id$/).each do |foreign_key_column|
bt_model_class = add_belongs_to(model, foreign_key_column.chomp("_id"))
add_has_many model, bt_model_class
end
end
def add_belongs_to(model, bt_name)
return if model.reflections.keys.include?(bt_name)
bt_model_class = bt_name.classify.constantize
return if !models.include?(bt_model_class)
model.class_eval do
belongs_to bt_name.to_sym
end
return bt_model_class
end
def add_has_many(model, bt_model_class)
hm_name = model.name.underscore.pluralize
if !bt_model_class.reflections.keys.include?(hm_name)
bt_model_class.class_eval do
has_many hm_name.to_sym, dependent: :destroy
end
end
end
end
end
ActiveRecord::Base.connection # avoid silly warning in rails console
EZ::AssociationInjector.new.inject_associations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment