Scenarios

Generate a token

SecureRandom.urlsafe_base64
# 16 bytes of length is assumed if n is nil
(1..16).each {|n| l = SecureRandom.urlsafe_base64(n).length; puts "#{l == ((4.0/3)*n).ceil}: #{l}" }
# true: 2
# true: 3
# true: 4
# true: 6
# true: 7
# true: 8
# true: 10
# true: 11
# true: 12
# true: 14
# true: 15
# true: 16
# true: 18
# true: 19
# true: 20
# true: 22

The argument n specifies the length, in bytes, of the random number to be generated. The length of the result string is about 4\/3 of n.

Find a single record

# do not use in scope, due to scope is designed for chainable
AnyModel.where("CONDITIONS").first

AnyModel.where("CONDITIONS").first!
# raise exception if no recrod was found

AnyModel.find_by("ANY_ATTRIBUTE = ? AND ANY_ATTRIBUTE_DATE >= Now()", ANY_CRITERIA)

PORO object with error message

class AnyClass
  extend ActiveModel::Naming

  attr_accessor :any_attribute
  attr_reader   :errors

  def initialize
    @errors = ActiveModel::Errors.new(self)
  end

  def validate!
    errors.add(:any_attribute, "ERROR MESSAGE") if any_attribute.nil?
  end

  def read_attribute_for_validation(attr)
    send(attr)
  end

  def AnyClass.human_attribute_name(attr, options = {})
    attr
  end

  def AnyClass.lookup_ancestors
    [self]
  end
end

or

class AnyClass
  include ActiveModel::Model
  include ActiveModel::Validations
end

Mock a ActiveRecord::RecordInvalid

allow_any_instance_of(AnyActiveModel).to receive(:save!).and_raise(ActiveRecord::RecordInvalid.new(ANY_ACTIVE_RECORD))

Generate a random number between a range

rand(X..Y)
# a random number between X and Y
rand(1..3)
# 1/2/3

FactoryGirls, a combination of traits of factory

FactoryGirl.define do
  factory :any_factory_name do
    attribute_1 "DUMMY1"
    attribute_2 "DUMMY2"

    trait :t1 do
      attribute_3 "SOMETHING"
    end

    trait :t2 do
      attribute_4 SOME_FORMULAT
    end

    factory :t1_and_t2_factory_name, traits: [:t1, :t2]
    # a combination of traits of factory 
  end
end

# any_spec.rb
let(:something) { create(:t1_and_t2_factory_name) }

Modified .rbenv-vars, how to restart rails app?

# in the app's root 
touch tmp/restart.txt

find the newest record

AnyModel.last # default order by primary key
AnyModel.order(:id).last # asc
AnyModel.order(id: :desc).last

#last

Race conditions

Skip the migrations which have been done

While your project grows and more and more developers are working together. Everyone may add different migrations on different branches. You switch to the branch with new migrations so you run rake db:migrate. Afterward, you switch to another branch with other new migrations and includes the same migrations you've just run. And you run rake db:migrate again. Then the database complains about some columns have already exists....

# make sure the migration had been executed successfully
$ rails c
> ActiveRecord::SchemaMigration.find_by(version: "YYYYMMDDHHMMSS")
# =>  #<ActiveRecord::SchemaMigration:0x007f8e8daed738 version: "YYYYMMDDHHMMSS">
# it had been executed!

# a workaround
# temporily comment out the migrations code, do not commit the changes to your repo
class CreateXxxXxxXxx < ActiveRecord::Migration
  def change
    # create_table :xxx_xxx_xxx do |t|
    #   t.string :xxx_xxx
    #   t.string :xxx_xxx
    # end
  end
end

# or

class CreateXxxXxxXxx < ActiveRecord::Migration
  def change
    create_table :xxx_xxx_xxx do |t|
       t.string :xxx_xxx
       t.string :xxx_xxx
     end
  rescue => e
    puts "manually skip"
  end
end

# checkout the migration temporily changes
$ git checkout db/migrate/

Log current stack trace in Ruby

Rails.logger.debug "#{caller.join("\n")}"

Where is the method's definition?

source_location

% rails c
% 3.method(:days).source_location
# => => [".../.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5.1/lib/active_support/core_ext/numeric/time.rb", 34]

Find the inherent tree

ancestors

% rails c
% Integer.ancestors
# => [Integer, Sankhya, Numeric, Comparable, Object, PP::ObjectMixin, Nori::CoreExt::Object, FriendlyId::ObjectUtils, ActiveSupport::Dependencies::Loadable, JSON::Ext::Generator::GeneratorMethods::Object, Kernel, BasicObject]

Show object's public methods

any_object.public_methods
# show all delegated available public methods
any_object.public_methods(false)

String.public_methods.count
# => 201
irb(main):016:0> String.public_methods(false).count
# => 13

get currently executing method name

__method__.to_s
__callee__.to_s
  • __method__
  • __callee__
  • __method__ vs __callee__

pass arguments to a rake task

namespace :dev do
  desc 'pass arguments to a task'
  task :test, %i[arg1 arg2 arg3]=> :environment do |task, args|
    args.with_defaults(arg1: -1, arg2: -2, arg3: -3)
    arg1 = args[:arg1].to_i if args[:arg1]
    arg2 = args[:arg2].to_i if args[:arg2]
    arg3 = args[:arg3].to_i if args[:arg3]
    puts task
    puts args
    puts "arg1=#{arg1}"
    puts "arg2=#{arg2}"
    puts "arg3=#{arg3}"
  end
end

% rake dev:test
#=> dev:test
#=> {:arg3=>-3, :arg2=>-2, :arg1=>-1}
#=> arg1=-1
#=> arg2=-2
#=> arg3=-3

% rake dev:test[10,20,30]
#=> {:arg1=>"10", :arg2=>"20", :arg3=>"30"}
#=> arg1=10
#=> arg2=20
#=> arg3=30

Calculating how many months between two specific dates?

# any_date2 >= any_dae1
(any_date2.year * 12 + any_date2.month) - (any_date1.year * 12 + any_date1.month)

Class Alias

class A; end
# rename class A to B
class B; end

# config/initializers/
A = B
a = A.new
# => #<B:0x007fda4365b7e0

Output array to CSV in Ruby

require 'csv'
CSV.open("any_file_name.csv", "w") do |csv|
  any_data_array.each { |data| csv << [data] }
end
# file will be stored at project's root

Reference

results matching ""

    No results matching ""