Bishal Shrestha Full Stack Ruby on Rails Developer Full Stack Ruby on Rails Developer from Nepal.
Currently in Melbourne, Australia.

How to Generate Only Models, Controllers and Views in Rails Scaffold

In order to generate only models, views and controllers using the scaffold generator in Rails add following configurations in your application.rb file

  # Disable assets, helper and specs generation during scaffold
  config.generators do |g|
    g.assets false
    g.helper false
    g.jbuilder false
    g.stylesheets false
    g.test_framework nil
  end

How to Wrap Text Break Long Lines in Pre Tag HTML

Wrapping text in HTML CSS is hard in itself, now you have to wrap text and break longer lines inside a <pre> tag!

No worries.

  pre.text-breaker {
    overflow-x: auto;
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    white-space: -pre-wrap;
    white-space: -o-pre-wrap;
        word-wrap: break-word;
  }

Now add the .text-breaker class to those <pre> tags for your peace of mind.

Use Vcr and Webmock to Stub Your Http Requests Testing With Rspec in Rails



Image of VCR

Why Use VCR?

Testing attributes that depend on external web requests, for example API calls, may be time consuming and costly. Not only do this calls slow down the evaluation run time, they’ve use up API calls, causing you to hit your rate limit much quicker. This has the potential to, at best, induce you to pause in your testing and restart afterwards and, at worst, violate a feature of your program temporarily.

So, how do we analyze our app’s ability to, let us say, authorize a user with multitasking and Twitter actions such as regain a user’s friends or latest tweets?

There are a number of methods by which we can “stub” or replace external internet requests in our evaluation suite. To find out more about them, you may read this amazing ThoughtBot article. Here, we’ll be focusing specifically on using VCR to solve this problem.

How does VCR Work?

As soon as you configure VCR and set up your test package to use it (more on that in a minute), you conduct your test suite. The first time the tests run, they’ll send outside web requests. Those requests, and their answer will be listed on a”tape”, i.e. a document on your spec directory. Next, every subsequent time you run your test package, VCR, with the support of this WebMock stone, will stub out the external web requests and rather re-play the tape.

Setting Up VCR

1 . Add the VCR gem and the WebMock gem for your Gemfile and bundle install

gem 'webmock'  
gem 'vcr'  

2 . Configure VCR:

Create a folder service inside your spec folder. Create a document, vcr_setup.rb inside of spec/support. Fill it out with the next code:

VCR.configure do |c|  
  #the directory where your cassettes will be saved
  c.cassette_library_dir = 'spec/vcr'
  # your HTTP request service. 
  c.hook_into :webmock
end  

3 . Setup WebMock:

In your spec_helper file, add the following lines:

require 'webmock/rspec'  
WebMock.disable_net_connect!(allow_localhost: true)  

WebMock is a gem that stubs out the outside net requests. VCR utilizes WebMock to prevent external internet requests. VCR instead directs those requests into the cassettes.

4 . Write your tests using VCR. For the purposes of the example, we are going to be analyzing our TwitterApi class. The TwitterApi course initializes to configure the customer, employing the Twitter gem. Here, we’ll take a look at an evaluation for the find_user_for method, which should take in a debate of a username and return the appropriate Twitter User object:

describe TwitterApi do  
  let(:client) {TwitterApi.new}

  describe "#find_user_for" do 
    it "given a username, it returns the correct user object" do 
      VCR.use_cassette('twitter/find_user_for') do
        user = client.find_user_for("sm_debenedetto")
        expect(user.class).to eq(Twitter::User)
        expect(user.username).to eq("sm_debenedetto") 
      end
    end
  end

Let us take a closer look at at the it block that utilizes VCR:

  • First we inform VCR to record the”cassette” (the petition to and response from the Twitter API), to a file spec/vcr/twitter/find_user_for.

  • Then we proceed with our usual RSpec test. Next time that the test suite runs, VCR will use WebMock to take over the internet request and use the data in the cassette file.

And we’re done! You’re ready to stub out internet requests in your test suites easily.

Javascript Writing Guidelines

Code Conventions for the JavaScript Programming Language

This is a set of coding conventions and rules for use in JavaScript programming.

The long-term value of software to an organization is in direct proportion to the quality of the codebase. Over its lifetime, a program will be handled by many pairs of hands and eyes. If a program is able to clearly communicate its structure and characteristics, it is less likely that it will break when modified in the never-too-distant future. Code conventions can help in reducing the brittleness of programs.

All of our JavaScript code is sent directly to the public. It should always be of publication quality. Neatness counts.

JavaScript Files

JavaScript programs should be stored in and delivered as .js files.

JavaScript code should not be embedded in HTML files unless the code is specific to a single session. Code in HTML adds significantly to pageweight with no opportunity for mitigation by caching and compression.

Whitespace

Where possible, these rules are consistent with centuries of good practice with literary style. Deviations from literary style should only be tolerated if there is strong evidence of a significant benefit.

Blank lines improve readability by setting off sections of code that are logically related.

Blank spaces should always be used in the following circumstances:

  • A keyword followed by ( left parenthesis should be separated by a space. Spaces are used to make things that are not invocations look less like invocations, so for example, there should be space after if or while.
        while (true) {
  • A blank space should not be used between a function value and its invoking ( left parenthesis. This helps to distinguish between keywords and function invocations.
  • The word function is always followed with one space.
  • No space should separate a unary operator and its operand except when the operator is a word such as typeof.
  • All binary operators should be separated from their operands by a space on each side except . period and ( left parenthesis and [ left bracket.
  • Every , comma should be followed by a space or a line break.
  • Each ; semicolon at the end of a statement should be followed with a line break.
  • Each ; semicolon in the control part of a for statement should be followed with a space.

Every statement should begin aligned with the current indentation. The outermost level is at the left margin. The indentation increases by 4 spaces when the last token on the previous line is { left brace, [ left bracket, ( left paren. The matching closing token will be the first token on a line, restoring the previous indentation.

The ternary operator can be visually confusing, so wrap the entire ternary expression in parens. The condition, the ? question mark, and the : colon always begins a line, indented 4 spaces.

    let integer = function (
        value,
        default_value
    ) {
        value = resolve(value);
        return (
            typeof value === "number"
            ? Math.floor(value)
            : (
                typeof value === "string"
                ? value.charCodeAt(0)
                : default_value
            )
        );
    };

Clauses (case, catch, default, else, finally) are not statements and so should not be indented like statements.

Use of tabs invites confusion, argument,and crying, with little compensating value. Do not use tabs. Use space.

Comments

Be generous with comments. It is useful to leave information that will be read at a later time by people (possibly your future self) who will need to understand what you have done and why. The comments should be well-written and clear, just like the code they are annotating. An occasional nugget of humor might be appreciated. Frustrations and resentments will not.

It is important that comments be kept up-to-date. Erroneous comments can make programs even harder to read and understand.

Make comments meaningful. Focus on what is not immediately visible. Don’t waste the reader’s time with stuff like

    // Set i to zero.

    i = 0; 

Use line comments, not block comments. The comments should start at the left margin.

Variable Declarations

All variables should be declared before used. JavaScript does not require this, but doing so makes the program easier to read and makes it easier to detect undeclared variables that may become implied. Implied global variables should never be used. Use of global variables should be minimized.

    let currentEntry; // currently selected table entry
    let level;        // indentation level
    let size;         // size of table

Function Declarations

All functions should be declared before they are used. Inner functions should follow the let statement. This helps make it clear what variables are included in its scope.

There should be no space between the name of a function and the ( left parenthesis of its parameter list. There should be one space between the ) right parenthesis and the { left curly brace that begins the statement body. The body itself is indented four spaces. The } right curly brace is aligned with the line containing the beginning of the declaration of the function.

    function outer(c, d) {
        let e = c * d;

        function inner(a, b) {
            return (e * a) + b;
        }

        return inner(0, 1);
    }

This convention works well with JavaScript because in JavaScript, functions and object literals can be placed anywhere that an expression is allowed. It provides the best readability with inline functions and complex structures.

    function getElementsByClassName(className) {
        let results = [];
        walkTheDOM(document.body, function (node) {
            let array;                // array of class names
            let ncn = node.className; // the node's classname

// If the node has a class name, then split it into a list of simple names.
// If any of them match the requested name, then append the node to the list of results.

            if (ncn && ncn.split(" ").indexOf(className) >= 0) {
                results.push(node);
            }
        });
        return results;
    }

If a function literal is anonymous, there should be one space between the word function and the ( left parenthesis. If the space is omitted, then it can appear that the function’s name is function, which is an incorrect reading.

    div.onclick = function (e) {
        return false;
    };

    that = {
        method: function () {
            return this.datum;
        },
        datum: 0
    };

Use of global functions should be minimized.

When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.

let collection = (function () {
    let keys = [];
    let values = [];

    return {
        get: function (key) {
            let at = keys.indexOf(key);
            if (at >= 0) {
                return values[at];
            }
        },
        set: function (key, value) {
            let at = keys.indexOf(key);
            if (at < 0) {
                at = keys.length;
            }
            keys[at] = key;
            values[at] = value;
        },
        remove: function (key) {
            let at = keys.indexOf(key);
            if (at >= 0) {
                keys.splice(at, 1);
                values.splice(at, 1);
            }
        }
    };
}());

Names

Names should be formed from the 26 upper and lower case letters (A .. Z, a .. z), the 10 digits (0 .. 9), and _ underbar. Avoid use of international characters because they may not read well or be understood everywhere. Do not use $ dollar sign or \ backslash in names.

Do not use _ underbar as the first or last character of a name. It is sometimes intended to indicate privacy, but it does not actually provide privacy. If privacy is important, use closure. Avoid conventions that demonstrate a lack of competence.

Most variables and functions should start with a lower case letter.

Constructor functions that must be used with the new prefix should start with a capital letter. JavaScript issues neither a compile-time warning nor a run-time warning if a required new is omitted. Bad things can happen if new is not used, so the capitalization convention is the only defense we have.

Global variables in browsers should be in all caps.

Statements

Simple Statements

Each line should contain at most one statement. Put a ; semicolon at the end of every simple statement. Note that an assignment statement that is assigning a function literal or object literal is still an assignment statement and must end with a semicolon.

JavaScript allows any expression to be used as a statement. This can mask some errors, particularly in the presence of semicolon insertion. The only expressions that should be used as statements are assignments, invocations, and delete.

Compound Statements

Compound statements are statements that contain lists of statements enclosed in { } curly braces.

  • The enclosed statements should be indented four more spaces.
  • The { left curly brace should be at the end of the line that begins the compound statement.
  • The } right curly brace should begin a line and be indented to align with the beginning of the line containing the matching { left curly brace.
  • Braces should be used around all statements, even single statements, when they are part of a control structure, such as an if or for statement. This makes it easier to add statements without accidentally introducing bugs.

Labels

Statement labels should be avoided. Only these statements should be labeled: while, do, for, switch.

return Statement

The return value expression must start on the same line as the return keyword in order to avoid semicolon insertion.

if Statement

The if class of statements should have the following form:

   if (condition) {  
        statements  
    }  

    if (condition) {  
        statements  
    } else {  
        statements  
    }  

    if (condition) {  
        statements  
    } else if (condition) {  
        statements  
    } else {  
        statements  
    }`

for Statement

A for class of statements should have the following form:

    for (initialization; condition; update) {  
        statements
    }

while Statement

A while statement should have the following form:

    while (condition) {  
        statements  
    }

do Statement

A do statement should have the following form:

   do {  
        statements  
    } while (condition);

Unlike the other compound statements, the do statement always ends with a ; semicolon.

switch Statement

A switch statement should have the following form:

  switch (expression) {  
    case expression:  
        statements  
    default:  
        statements  
    }

Each case is aligned with the switch. This avoids over-indentation. A case label is not a statement, and should not be indented like one.

Each group of statements (except the default) should end with break, return, or throw. Do not fall through.

try Statement

The try class of statements should have the following form:

    try {
        statements  
    } catch (variable) {
        statements  
    }  

    try {
        statements  
    } catch (variable) {
        statements  
    } finally {
        statements  
    }

continue Statement

Avoid use of the continue statement. It tends to obscure the control flow of the function.

with Statement

The with statement should not be used.

{} and []

Use {} instead of new Object(). Use [] instead of new Array().

Use arrays when the member names would be sequential integers. Use objects when the member names are arbitrary strings or names.

, comma Operator

Avoid the use of the comma operator. (This does not apply to the comma separator, which is used in object literals, array literals, and parameter lists.)

Assignment Expressions

Avoid doing assignments in the condition part of if and while statements.

Is

    if (a = b) {

a correct statement? Or was

    if (a == b) {

intended? Avoid constructs that cannot easily be determined to be correct.

=== and !== Operators.

Use the === and !== operators. The == and != operators do type coercion and should not be used.

Confusing Pluses and Minuses

Be careful to not follow a + with + or ++. This pattern can be confusing. Insert parens between them to make your intention clear.

    total = subtotal + +myInput.value;

is better written as

    total = subtotal + Number(myInput.value);

so that the + + is not misread as ++. Avoid ++.

eval is Evil

The eval function is the most misused feature of JavaScript. Avoid it.

eval has aliases. Do not use the Function constructor. Do not pass strings to setTimeout or setInterval.

How to Upload Multiple Files With Manual File Uploader Only With Activestorage in Rails

With introduction of ActiveStorage in Rails 5.2 it has become easier to attach files to ActiveRecord models in Rails. So much so that Paperclip has decided to cease support for their gem and encouraging users to migrate to ActiveStorage for more streamlined solution.

While ActiveStorgae provides straightforward ways to attach files to models using has_one_attached and has_many_attached, the official guides, stackoverflow and online tutorials don’t have an example of a simple uploader to only upload files to a service or local storage in case of development. An example could be a WYSIWYG editor file uploader.

A simple file uploader can be written using ActiveStorage::Blob and url_for. Here we will see an example to upload multiple images using a simple uploader with ActiveStorage.

First we might define route to our controller like:

  # config/routes.rb

  post 'uploader/image', to: 'uploader#image'

In our controller:

  
  # app/controllers/uploader_controller.rb

  class UploaderController < ApplicationController
    def index; end

    def image
      images_uploader = ImagesUploader.new(files)
      if images_uploader.upload
        flash[:success] = 'Image successfully uploaded.'
      else
        flash[:warning] = 'Image could not be uploaded. Try uploading .png or .jpg'
      end
      redirect_back(fallback_location: root_path)
    end

    private

    def files
      @files ||= params[:files]
    end
  end

We try to avoid putting too much logic in controller. So, we put the ImageUploader in a namespaced directory inside the controllers dir.

  # app/controllers/uploader_controller/images_uploader.rb

  require 'file_upload_service'

  class UploaderController
    # Class to upload images.
    class ImagesUploader
      attr_reader :files

      def initialize(files)
        @files = files
      end

      def upload
        return false if invalid_file_types
        files.each do |file|
          FileUploadService.upload(file)
        end
      end

      private

      def invalid_file_types
        (files.map(&:content_type) & %w[image/png image/jpeg]).empty?
      end
    end
  end

We place the file upload logic sperate in lib dir. So, that now it is easier if we want to create another uploader for .pdf file type or testing.

  
  # /lib
  # Used to upload file using ActiveStorage
  class FileUploadService
    def self.upload(file)
      ActiveStorage::Blob.create_after_upload!(
        io: file,
        filename: file.original_filename,
        content_type: file.content_type
      )
    end
  end

Create a simple form with file upload fields taking multiple files at once:

  
  # app/views/uploader/index.html.erb

  <div class="row">
    <div class="col-lg-6 mx-auto m-5">
      <h3>Upload Images</h3>
      <%= form_tag uploader_image_path, method: 'post', multipart: true do %>
        <%= file_field_tag :files, name: 'files[]', multiple: true, class: 'btn btn-primary', required: true %>
        <%= submit_tag 'Upload', class: 'btn btn-primary' %>
      <% end %>
      <small><em>only .png and .jpg</em></small>
    </div>
  </div>

And just like that we have a file uploader we can use to upload files straight to our preferred service. Write to me at [email protected] with questions or leave a comment. Cheers!

How to Assign Ruby Variable to Javascript Variable in Erb Rails

  var currentUserRole = '<%= current_user.role_name %>';

What Is Migration in Rails for Beginners

Definition

A migration represents a change we either want to make to a database as a whole, or to the data contained within the database, and it’s expressed in a source file in database-independent terms. These changes can update both the database schema and the data in the database tables. We apply these migrations to update our database, and we can unapply them to roll our database back.

Generate Migration

I am assuming you have a Rails app setup. And if not:

rails new store # :)
cd store

A migration can be generated in Rails with help of a command.

bin/rails generate migration create_products title:string description:text image_url:string price:decimal

This is going to generate a migration file logging out something like this in your bash:

invoke active_record
create    db/migrate/20180314132617_create_products.rb
create    app/models/product.rb

The migration has a UTC-based timestamp prefix ( 20180314132617 ), a name ( create_products ), and a file extension ( .rb , because it’s Ruby code).

The timestamp will be different for you as well, times change.

Applying the Migration

Now that we have out instructions ready to tell it Rails to run it. It’s time we do that, tell Rails to please run the migration.

But before that, we want to make some edits in the migration instructions. Let’s say we want the price of our products to have eight digits of significance and two digits after the decimal.

class CreateProducts < ActiveRecord::Migration[5.1]
  def change
    create_table :products do |t|
      t.string :title
      t.text :description
      t.string :image_url
      t.decimal :price, precision: 8, scale: 2 # <<

      t.timestamps
    end
  end
end

Now that we have what we want, we are now ready to apply this migration to our development database. We can do this with help of Rails command bin/rails db:migrate:

~/workspace/store$ bin/rails db:migrate
== 20180314132617 CreateProducts: migrating ===================================
-- create_table(:products)
   -> 0.0013s
== 20180314132617 CreateProducts: migrated (0.0018s) ==========================

And that’s it Rake (which is also just another program), looks for all the unimplemented migrations in the /db/migrate/ directory and applies them.

We must now have a table named products in our development database.

How to Check if a Record Will Respond to a Method Or Has a Certain Attribute in Rails

To check if a class or instance variable to see if it has an attribute we can use the ruby method has_attribute?(:method_name)

However, when we are dealing with an instance of ActiveRecord in Rails, sometimes we may come across situation when we want to see if a instance variable has a belongs_to or has_many relationship with other models. In that case, we can make use of

example.respond_to?(:method_name)

This solution is more generic and feasible in order to avoid no method error in Rails.

How to Replace Local Git Branch With Remote Branch Completely and Vice Versa

# How to replace local branch completely with remote branch in git

git checkout master
git reset --hard origin/master


# How to replace remote branch completely with local branch in git

git push --force origin master

How to Combine Two Arrays and Form a Hash in Ruby

Say we have two different arrays:

  brands = ["Nike", "Adidas", "Under Armour", "Puma"]
  products = [["shoes", "shirts"],
              ["shoes", "caps", "cleats"],
              ["compressions", "training bands"],
              ["bags", "shoes"]]

and we want something like:

  {
    "Nike"=>["shoes", "shirts"],
    "Adidas"=>["shoes", "caps", "cleats"],
    "Under Armour"=>["compressions", "training bands"],
    "Puma"=>["bags", "shoes"]
  }

This can be achieved easily with this line of code:

  Hash[brands.zip(products)]

This has been useful to me in many scenarios than I can imagine.

Coercion in JavaScript

Coercion in JavaScript is a feature in JavaScript language, which is simply forcefully converting a data type to another data type based upon a predefined precedence table (listed in Mozilla I think go figure haha).

JavaScript implements dynamic typing to define it’s variables. So when you pass two different data types into an operator, it won’t necessarily throw an error.

Example:

"2" < 0 # -> false

This should be a strange event if you are new to programming in general or coming from some other programming paradigm which has static typing like C or Java. The case is more interesting when you consider this particular example:

"2" == 2 # -> true

Whereas,

"2" === 2 # -> false

Popular explanation I have heard on this is === operator compares the data type along with the values. Thus, returning false upon it’s deployment. Which makes sense.

But what is really happening under the hood is that, JavaScript engine coerces the "2" in first example to 2 of integer type and compare it to 2 in the right side of == operator.

Whereas in the second example it just SKIPS THE COERCION. This is important to understand that the engine is simply skipping the coercion step, not comparing the data type.

So, the result is the same but the reason is different!

Hope you felt enlightened as I felt when I found this out!! Cheers!

How to Find Random Record With Condition in Rails

Use the following ActiveRecord query to find a random record fulfilling a condition:

Topic.order('RANDOM()').where(exam_id: 1).first

How to List All the Rake Tasks in Rails

You can list all the rake tasks in a Rails project from the project root directory with this command:

rake -T -A

How to Redirect Back to Current Page After Sign in Using Devise in Rails

As pointed out in the official documentation, the simpler solution would be to simply add this to your application_controller.rb:

  class ApplicationController < ActionController::Base


  private
  
  # If your model is called User
  def after_sign_in_path_for(resource)
    session["user_return_to"] || root_path
  end

Important Note (Which I also overlooked) is that for this to work you will need to call authenticate_user! method, available by default in Devise, in your controller’s before_action:. This will call store_location_for available out of the box in Devise, and the rest is handled by the above code in the application_controller.rb, thus eliminating the need to rewrite code to save requesting url.

How to Use a Seperate Gemset For a Rails Project Using Rvm

To use a specific gemset using RVM make sure you have RVM installed first.

  rvm -v

If you have it installed, create a dir where to setup your new project in Rails and follow the rest of the commands:

  mkdir myapp
  cd myapp
  $ rvm gemset create [name of gemset]
  rvm --rvmrc [ruby version]@[name of gemset]
  cd ../
  cd [app dir] # To refresh the dir. On cd back to dir you will be asked if to execute the shell script. Choose Yes
  bundle install

Now you will have your project specific gemset at [email protected] (example).

Cheers!

Create a Rails Project With Specific Version of Rails

You have several versions of Rails installed in your system. But you want to create a Rails app with a previous version for whatever reason. Here is how you do it using bundler:

  $ mkdir my_rails_app
  $ cd my_rails_app
  $ touch Gemfile
  $ echo "source 'https://rubygems.org'"
  $ echo "'rails', '~> 4.2.6'"
  $ bundle install
  $ bundle exec rails new . --force
  $ bundle update

You have successfully created a specific rails app using Bundler.

How to List Out All the Models in Rails Console

If you want to see all the models in a Rails project from the console, you can use the following commands:

Rails 4 and before:

ActiveRecord::Base.descendants

Rails 5 and later:

ApplicationRecord.descendants

Cheers!

Add Key Binding Or Keyboard Shortcut in Atom

Recently switched to Atom and wanted to add some personal key binding to the editor. Just to move to the end of a line or front of a line.

So, to basically add ctrl + l to move to end of line, the steps are:

  1. ctrl + , Open the settings
  2. Go to Keybindings
  3. Find your keymap file link and open it
  4. Add the Keybindings for example:
1
2
3
4
5
6
  'atom-text-editor':
    'ctrl-j': 'editor:move-to-first-character-of-line'
    'ctrl-l': 'editor:move-to-end-of-screen-line'
    'ctrl-shift-j': 'core:move-up'
    'ctrl-shift-m': 'core:move-down'
  

You can find the binding values in the right side if you look around searching in keybindngs section of settings in step 2.

Git Conflict Markers Which Is Which

As an amateur developer every time you try to merge or update a branch with the remote branch you come across a merge conflict. So, you basically want to update your local branch with what’s in the remote master. You go into the file which have conflicts and there are 2 blocks of code.

One is between HEAD and ======= Another between ======== and adf32834h43932h3nf (commit)

So, the thing to remember is: HEAD is you. It is the latest commit in your local branch.

And the other within the other commit is the changes other have made and is merged into the master you are pulling from.

How to Force Close a Tab in Chrome

Shift + ESC

Open the Chrome task manager and close that unresponsive tab. That’s it!

How to Style Multiple Pseudo Selectors in Sass

Style multiple CSS pseudo selectors, like :hover, :active, :focus, :visited for anchor tag, in SASS using following example syntax:

1
2
3
4
a
  &:hover, &:active, &:focus, &:visited
    color: turoquoise
    transition: all 0.8s ease

Cheers!

How to Create Jekyll Posts Easily Using Ruby

I just got tired of copying pasting the Jekyll front matter and renaming the post file name with the precise date and title. So, I created a small Ruby script that will take the title and generate a post template for me.

1. Create the file

In your Jekyll directory create a file create_post.rb in your ./_posts folder and open in a text editor:

  $ cd _posts
  $ touch create_post.rb
  $ nano create_post.rb

2. Write the script.

Here is the script I wrote.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env ruby

class JekyllHelper
  ESC_CHAR = %w(the a an and in of but if to)

  def self.titalize(input)
    title = input.split(" ").map do |word|
      if !ESC_CHAR.include? word
        word.capitalize
      else
        word
      end
    end

    title.first.capitalize!
    '"' + title.join(" ") + '"'
  end

  def self.create_post(title)
    file = File.open(Time.now.strftime("%Y-%m-%d-" "#{title.downcase.split(" ").join("-")}.markdown"), "w")
    file.puts("--- \nlayout: post \nauthor: Bishal \ntitle: #{self.titalize(title)} \ndate: #{Time.now.strftime('%Y-%m-%d %H:%M:%S %z')} \npermalink: posts/#{title.downcase.split(" ").join("-")}/ \ncategories: \ndescription: \ncomments: true \n---")
    file.close
  end
end

JekyllHelper.create_post(ARGV[0])

Don’t forget to change the author to your name.

3. Run the script

In your project directory cd to _posts folder and run the script passing your post title as parameter.

  $ ruby create_post.rb "How to create posts easily in Jekyll"

Now you will have a new post markdown in your _posts folder with the current date and the front matter template. description and categories fields are left empty for you to fill up.

That’s it! Hope this was helpful.

How to Center Elements Vertically in a div Usig CSS

Create a helper (utility) class say .has-vertically-centered-items

1
2
3
4
5
.has-v-centered-items {
  display: flex;
  justify-content: center; /* align horizontal */
  align-items: center; /* align vertical */
}

Hope that helps. Cheers!

How to Rename GIT Branch

1. Renaming the local branch

If you are in the branch you want to rename:

  git branch -m new_name

If you are outside the branch:

  git branch -m old_branch new_name

2. Delete the old_name branch in remote and push the new_name branch

  git push origin :old_name new_name

3. Reset the upstream branch for the new_name branch

  git push origin -u new_name

How to Run Ruby Code Periodically

At times you want to run a block of code, say every 5 seconds. How do you do that? Here is how:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def every_n_seconds(n)
  loop do
    start_time = Time.now
    yield
    time_left = n - (start_time - Time.now)
    sleep(time_left)
  end
end

every_n_seconds(5) { puts "#{Time.now.strftime("%dth, %B %H:%M:%S (%Z)")}: Wake up!"}

/ 06th, October 12:05:25 (NPT): Wake up!
/ 06th, October 12:05:30 (NPT): Wake up!
/ 06th, October 12:05:35 (NPT): Wake up!
/ 06th, October 12:05:40 (NPT): Wake up!