Skip to content

Instantly share code, notes, and snippets.

@fobiasmog
Last active January 10, 2025 11:06
Show Gist options
  • Save fobiasmog/bc1418d815bec58f00f8fb0dca6fb920 to your computer and use it in GitHub Desktop.
Save fobiasmog/bc1418d815bec58f00f8fb0dca6fb920 to your computer and use it in GitHub Desktop.
Ruby & Rails hacks

Проверка, что все элементы в массиве идут по порядку от 1 до Х

arr.select.with_index { |e, i| e == i+1 }.size == arr.size

extend self

Полезен, когда нужно сделать метод модуля

module X
  extend self
  def x
    pp 'hello'
  end
end

[2] pry(main)> X.x
"hello"

module Y
  def y
    pp 'hi'
  end
end

[4] pry(main)> Y.y
NoMethodError: private method `y' called for Y:Module
from (pry):13:in `__pry__'

Рекурсивно превратить хэш в объект

require 'ostruct'
x = {email: {value: '[email protected]'}}
JSON.parse x.to_json, object_class: OpenStruct

Не ставить локально при bundle install модули из продовской группы

bundle config set without 'production'

Найти расположение метода объекта

User.first.method(:myCustomMethod).source_location
=> ["some/path/to/file.rb", 53]

Include vs prepend

module X
  def foo = pp 'foo X'
end

module Y
  def foo = pp 'foo Y'
end

class A
  include X
  def foo = pp 'foo A'
end

class B
  prepend X
  def foo = pp 'foo B'
end

class C
  prepend X
  prepend Y
  def foo = pp 'foo B'
end

A.new.foo => foo A
B.new.foo => foo X
C.new.foo => foo Y

A.ancestors => [A, X, ...]
B.ancestors => [X, A, ...]
C.ancestors => [Y, X, A, ...]

GRAPE API Все апи роуты и их модули

API.routes.map {|a| "#{a.request_method} #{a.pattern.path} #{a.app.options[:for]}" }

API.routes.map {|a| "#{a.request_method} #{a.pattern.path} #{a.app.options[:for]}" }.filter { |e| e.match('\/lms\/employee-roles\/.*\/co-authors') }

??!! include/preload/joins ломают анскоуп дефолт скоупа — ибо если ты до этого анскоупил связь, но сделал includes(:user) то этот инклюд будет сделан с with_default_scope

has_one :user
scope :with_unscoped_user, -> { unscoped }

или?

belongs_to :with_deleted_user, -> { unscoped }

Payments.with_unscoped_user.includes(:user)

User.all.update(uid: SecureRandom.uuid) не работает как ожидается на многих записях

Freeze the class variables

class X
  attr_accessor :a
  def initialize(a)
    @a = a
    freeze
  end

And now you can't do this

x = X.new(1)
x.a = 2

Non mutable params through the class

# for example we have a code like this
class UserService
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  def modify_some_name_and_return_back
    return name.reverse! # <<-- here we've just mutate the object, which wasn't copied in class constructor
  end
name = params[:name]
user = UserService.new(name)
new_name = user.modify_some_name_and_return_back
return {
  before: user.name,
  after: new_name
} # that's why here we'll have before == after

here is better to use @name = name.dup (name.object_id in and out the class constructor are same)

Fake run bunch of migrations

find db/migrate/ | sed 's/db\/migrate\///' | awk -v sq="'" -v dq='"' -F '_' '{print "bundle exec rails runner ", dq, "ActiveRecord::SchemaMigration.create! version: ", sq $1 sq, dq}' | bash
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment