Skip to content

Instantly share code, notes, and snippets.

@ram-ai-kumar
Last active January 16, 2024 09:37
Show Gist options
  • Select an option

  • Save ram-ai-kumar/e3ae6ac269ca7a28bb2ee21eed824e91 to your computer and use it in GitHub Desktop.

Select an option

Save ram-ai-kumar/e3ae6ac269ca7a28bb2ee21eed824e91 to your computer and use it in GitHub Desktop.

Revisions

  1. ram-ai-kumar revised this gist Jan 16, 2024. 2 changed files with 98 additions and 23 deletions.
    105 changes: 86 additions & 19 deletions seeds.rb
    Original file line number Diff line number Diff line change
    @@ -22,12 +22,13 @@

    # seed constants
    seeds = {
    users: 5,
    devices: 10,
    alarms: 10,
    devices: 10,
    groups: 5,
    locations: 5,
    messages: 10,
    video_calls: 20,
    groups: 5
    users: 5,
    video_calls: 20
    }

    # start a block that will reset the logger on any error
    @@ -36,25 +37,91 @@
    # seeds/helper.rb
    # set the logger to what we need for the current environment
    #
    _logger = set_logger
    log_and_run "Seeding the database..."
    set_logger
    logrun before: "Seeding the database..."

    #
    # Users, that will be Admins
    #
    # delete existing
    log_and_run("Removing existing users...") { User.delete_all }
    # creates a randomly sized array of hashes, filled with attributes from factory
    # add them together with a single call
    users = Array.new(rand(1..seeds[:users])) { FactoryBot.attributes_for(:user) }
    User.insert_all(users)
    # add at least one known admin
    FactoryBot.create(:user,
    role: "admin",
    name: "Admin", email: "admin@bharat.in",
    password: "password", password_confirmation: "password")
    # log the result
    log_and_run "Added #{users.length + 1} users: #{users.first(5).pluck(:email).join(", ")}..."
    logrun after: "Added #{User.count} users: #{User.random(2).pluck(:email).join(", ")}..." do
    logrun(before: "Removing existing users...") { User.delete_all }

    # creates a randomly sized array of hashes, filled with attributes from factory
    users = Array.new(rand(1..seeds[:users])) { FactoryBot.attributes_for(:user).except(:password, :password_confirmation) }
    User.insert_all(users) # bulk insert
    # add at least one known admin
    FactoryBot.create(:user, role: "admin", name: "Admin", email: "admin@bharat.in")
    end
    # fetch data for further use
    user_ids = User.ids

    #
    # Devices
    #
    logrun after: "Added #{Device.count} devices: #{Device.random(2).pluck(:name).join(", ")}..." do
    logrun(before: "Removing existing devices...") { Device.delete_all }

    devices = Array.new(rand(1..seeds[:devices])) { FactoryBot.attributes_for(:device) }
    Device.insert_all(devices)
    end
    # fetch data for further use
    device_ids = Device.ids

    #
    # Alarms
    #
    logrun after: "Added #{Alarm.count} alarms..." do
    logrun(before: "Removing existing alarms...") { Alarm.delete_all }

    alarms = Array.new(rand(1..seeds[:alarms])) { FactoryBot.attributes_for(:alarm, user_id: user_ids.sample) }
    Alarm.insert_all(alarms)
    end

    #
    # Messages
    #
    logrun after: "Added #{Message.count} messages... #{Message.random.content}..." do
    logrun(before: "Removing existing messages...") { Message.delete_all }

    messages = Array.new(rand(1..seeds[:messages])) { FactoryBot.attributes_for(:message) }
    Message.insert_all(messages)
    end

    #
    # Video Calls
    #
    logrun after: "Added #{VideoCall.count} video_calls..." do
    logrun(before: "Removing existing video_calls...") { VideoCall.delete_all }

    video_calls = Array.new(rand(1..seeds[:video_calls])) do
    device_id_1, device_id_2 = device_ids.sample(2)
    FactoryBot.attributes_for(:video_call, source_id: device_id_1, target_id: device_id_2)
    end
    VideoCall.insert_all(video_calls)
    end

    #
    # Locations
    #
    logrun after: "Added #{Location.count} locations..." do
    logrun(before: "Removing existing locations...") { Location.delete_all }

    locations_array = Array.new(rand(1..seeds[:locations])) { FactoryBot.attributes_for(:location) }
    Location.insert_all(locations_array)
    end
    # fetch ids for further use
    location_ids = Location.ids

    #
    # Groups => Devices and Locations must be created before this
    #
    logrun after: "Added #{Group.count} groups..." do
    logrun(before: "Removing existing groups...") { Group.delete_all }

    rand(1..seeds[:groups]).times do
    group_with_devices(devices_count: rand(2..5), location_ids: location_ids)
    end
    end
    # rescue from any exception as StandardError
    # we need this to reset the logger back to original
    #
    16 changes: 12 additions & 4 deletions seeds__helper.rb
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,6 @@

    #
    # helper methods for seeding
    # seeds/helper.rb
    #

    #
    @@ -11,9 +10,13 @@
    # @param [String] message to log in the currently set logger
    # [Block] block to yield
    #
    def log_and_run(message = ".")
    Rails.logger.info message.to_s
    def logrun(**message)
    # show this message --before-- executing the block
    Rails.logger.info message[:before].to_s if message[:before]
    # run the block if given
    yield if block_given?
    # show this message --after-- executing the block
    Rails.logger.info message[:after].to_s if message[:after]
    end

    #
    @@ -22,13 +25,18 @@ def log_and_run(message = ".")
    # @return [Object] Logger object that we have set
    #
    def set_logger
    # remember the existing logger
    @pre_seed_logger = Rails.logger
    Rails.logger = Logger.new($stdout)
    # output to STDOUT only for development environment
    Rails.env.development? && Rails.logger = Logger.new($stdout)
    # example: ELK LogStash in production
    # Rails.env.production? && Rails.logger = LogStashLogger.new(type: :udp, host: 'localhost', port: 5044)
    end

    #
    # Reset the logger back to what it was before seeding
    #
    def reset_logger
    # reset back to pre-seed logger
    Rails.logger = @pre_seed_logger
    end
  2. ram-ai-kumar created this gist Jan 8, 2024.
    13 changes: 13 additions & 0 deletions factories__users.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    # frozen_string_literal: true

    # a simple user factory
    # factories/users.rb
    #
    FactoryBot.define do
    factory :user do
    name { Faker::Name.unique.name }
    email { Faker::Internet.email(domain: "bharat.in") }
    # some users will randomly be "admin"
    role { "admin" } if [true, false].sample
    end
    end
    68 changes: 68 additions & 0 deletions seeds.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    # frozen_string_literal: true

    # This file should ensure the existence of records required to run the application in every environment (production,
    # development, test). The code here should be idempotent so that it can be executed at any point in every environment.
    # The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup).
    #
    # Example:
    #
    # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
    # MovieGenre.find_or_create_by!(name: genre_name)
    # end

    # fail-fast with guard-clause
    #
    return if Rails.env.production?

    #
    # start seeding when not in production
    #
    require "factory_bot"
    require_relative "seeds/helper"

    # seed constants
    seeds = {
    users: 5,
    devices: 10,
    alarms: 10,
    messages: 10,
    video_calls: 20,
    groups: 5
    }

    # start a block that will reset the logger on any error
    #
    begin
    # seeds/helper.rb
    # set the logger to what we need for the current environment
    #
    _logger = set_logger
    log_and_run "Seeding the database..."

    # Users, that will be Admins
    #
    # delete existing
    log_and_run("Removing existing users...") { User.delete_all }
    # creates a randomly sized array of hashes, filled with attributes from factory
    # add them together with a single call
    users = Array.new(rand(1..seeds[:users])) { FactoryBot.attributes_for(:user) }
    User.insert_all(users)
    # add at least one known admin
    FactoryBot.create(:user,
    role: "admin",
    name: "Admin", email: "admin@bharat.in",
    password: "password", password_confirmation: "password")
    # log the result
    log_and_run "Added #{users.length + 1} users: #{users.first(5).pluck(:email).join(", ")}..."

    # rescue from any exception as StandardError
    # we need this to reset the logger back to original
    #
    rescue => e
    #
    # switch the logger back to what was earlier
    reset_logger
    #
    # raise the exception again to get rescued in the call chain
    raise e
    end
    34 changes: 34 additions & 0 deletions seeds__helper.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    # frozen_string_literal: true

    #
    # helper methods for seeding
    # seeds/helper.rb
    #

    #
    # Log and Run the block
    #
    # @param [String] message to log in the currently set logger
    # [Block] block to yield
    #
    def log_and_run(message = ".")
    Rails.logger.info message.to_s
    yield if block_given?
    end

    #
    # switch the logger to $stdout and use `logger.info` for status updates
    #
    # @return [Object] Logger object that we have set
    #
    def set_logger
    @pre_seed_logger = Rails.logger
    Rails.logger = Logger.new($stdout)
    end

    #
    # Reset the logger back to what it was before seeding
    #
    def reset_logger
    Rails.logger = @pre_seed_logger
    end