Check if command exists with shell script

if ! type gem > /dev/null; then
  echo 'gem command not found.'
fi


Tino

Delete merged git branches

Handy git command for deleting all local git branches that already merged git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

1
Stan

Simple Flux architecture with Vue.js

For a small app that only needs a simple state management pattern. I always use one component to hold the state of the app, a container. This act as a single source of truth for an app to refer to its states. Vue provides a mechanism to create a global event listener on the root level called EventBus which is a super simple way to mimic flux architecture.

All you need is one module that exports Vue as EventBus like so

// EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()


Then you can use it inside your container to listen to event from any component inside the app. I normally add the listener on created life cycle.

EventBus.$on('event-name', callback)


Then you can import EventBus into any of your components and you can triggers my-custom-event from anywhere without having to emit the event to that component's parent and repeat the whole process in every component in between the component that triggers the change and the target container.

// Goes directly to the global listener and triggers callback
EventBus.$emit('event-name')


That's it. If it's getting too complex, consider using Vuex.

Tino

My most used slack shortcuts

⌘-K(or T) to open the channel switcher (I navigate channels solely with this shortcut and have my slack set to hide all channels without new messages)

⌘-F opens the search box. Can modify searches with from:@user and in:#channel for extra awesomeness

Up Arrow will edit you last message; perfect for when you hit Enter too early or mispell things

+:emoji: react to the last message. Have to be quick so nobody else replies before you react though or you'll react to the wrong message

/remind [someone usually myself] [to do something] [at this time in words] not really a shortcut but is great for not forgetting simple tasks

The channel switcher also supports fuzzy matching to some extent. If a channel is named foo-bar you can type fb to show it. It's doesn't work so well with multi-user-dm's though.

828
Joe

Postgres Functions & Non-sargable Queries

Using postgres functions inside a where clause can make a query non-sargable.

Database Structure

tracks has_many artists

Non-Sargable Query

Using a LOWER function prevents DBMS engine from using indexes.

Track.joins(:artists).where('LOWER(tracks.display_name) LIKE ?', "eric clapton%").explain

Gather  (cost=1000.85..56714.32 width=4061)
   Workers Planned: 2
   ->  Nested Loop  (cost=0.85..55713.62 rows=3 width=4061)
         ->  Nested Loop  (cost=0.42..55708.37 rows=3 width=4069)
               ->  Parallel Seq Scan on tracks  (cost=0.00..55365.17 rows=41 width=4061)
                     Filter: (lower((display_name)::text) ~~* 'eric clapton%'::text)
               ->  Index Scan using index_artist_relations_on_artist_item_type_and_artist_item_id on artist_relations  (cost=0.42..8.36 rows=1 width=16)
                     Index Cond: (((artist_item_type)::text = 'Track'::text) AND (artist_item_id = tracks.id))
         ->  Index Only Scan using idx_35952_primary on artists  (cost=0.43..1.75 rows=1 width=8)
               Index Cond: (id = artist_relations.artist_id)


Sargable Query

Removing LOWER function allows DBMS engine to use indexes, resulting in faster execution.

Track.joins(:artists).where('tracks.display_name ILIKE ?', "eric clapton%").explain

Nested Loop  (cost=1497.60..2695.43 width=4061)
   ->  Nested Loop  (cost=1497.17..2684.94 rows=6 width=4069)
         ->  Bitmap Heap Scan on tracks  (cost=1496.75..1873.05 rows=97 width=4061)
               Recheck Cond: ((display_name)::text ~~* 'eric clapton%'::text)
               ->  Bitmap Index Scan on index_tracks_on_display_name  (cost=0.00..1496.73 rows=97 width=0)
                     Index Cond: ((display_name)::text ~~* 'eric clapton%'::text)
         ->  Index Scan using index_artist_relations_on_artist_item_type_and_artist_item_id on artist_relations  (cost=0.42..8.36 rows=1 width=16)
               Index Cond: (((artist_item_type)::text = 'Track'::text) AND (artist_item_id = tracks.id))
   ->  Index Only Scan using idx_35952_primary on artists  (cost=0.43..1.75 rows=1 width=8)
         Index Cond: (id = artist_relations.artist_id)


1
Abhi

Watch CI status on Github

When you have Github's hub installed, you can get the ci-status of your current branch like this:

$ hub ci-status
pending


If you install watch (e.g. brew install watch) you can continuously see the state:

$ watch hub ci-status


Const

Bash aliases and magic

I have a seperate file in my user folder named ~/.aliases. I use this to store all of my bash aliases. I use aliases a lot and add new ones regularly so I created a bash function to add new aliases on the fly.

addalias() {
  echo 'alias '$1'="'$2'"' >> ~/.aliases
  source ~/.aliases
}


Now you can add an alias from the terminal which will be available to the current session and all new sessions... shell $ addalias foo 'echo "bar"'

If I find myself using commands over and over I will create aliases shell alias g='git' alias b='bundle' alias be='bundle exec' alias bu='bundle update' alias r='bin/rails' alias rr='bin/rails routes' alias migration='bin/rails generate migration' alias migrate='bin/rails db:migrate; bin/rails db:migrate RAILS_ENV=test' alias rollback="rake db:rollback; RAILS_ENV=test rake db:rollback" alias push='git push origin HEAD' alias pr='git pull-request -c -m' alias ppr="git push origin HEAD && git pull-request -m" alias pulls='git browse -- pulls' alias prs='git pr list' pull() { git browse -- pull/'$1' } alias la='ls -a' alias ll='ls -al'

2
Joe

You can use FactoryBot for non ActiveRecord models

You can use FactoryBot's initialize_with method to initialize an object any way you like which allows you to factorize any of your objects at will

FactoryBot.define do
  factory :citizen_id_image, class: CitizenIdImagePresenter do
    image_url { 'https://placehold.it/200x200' }

    initialize_with { new(image_url: image_url) }
  end
end
build(:citizen_id_image)
#=> 


5
Joe

Force push previous commit to repo

If you push some code and want to force push a previous commit you can do so with shell git push origin +commit_sha^:branch_name

Where git interprets sha^ as the parent of sha and + as a forced non-fastforward push.

You can also use HEAD^ where ^ is the parent of HEAD so HEAD^^^ would push the commit 3 commits before the current commit. e.g. shell git push origin +HEAD^^^:feature/i_did_an_oopsie

1
Joe

Get current git branch name

git rev-parse --abbrev-ref HEAD


Ali