Rails : PaperTrail gem : Custom events to track fields changed

In my project, I was asked to keep track of changes in records. I found PaperTrails gem, and its found to be pretty useful.

But it lacks a straightforward feature to know the fields changed in that particular version. Then I thought to write custom event name so that I could grep the field_name I wish to check.

# == Schema Information
# Table name: tasks
#  id                :integer          not null, primary key
#  worker_id         :integer
#  customer_id       :integer
#  kind              :integer          default(0)
#  status            :integer          default(0)
#  note              :text
#  start_on          :datetime
#  complete_on       :datetime
#  started_on        :datetime
#  completed_on      :datetime
#  created_at        :datetime         not null
#  updated_at        :datetime         not null
#  driver_acceptance :integer          default(0)
#  refuel_id         :integer
#  shift_id          :integer

class Task < ActiveRecord::Base
  include Timeable
  # Update event-name on update
  before_save :paper_trail_events, on: :update

  enum status: { scheduled: 0, started: 1, skipped: 2, completed: 3, paused: 4, rescheduled: 5 }
  enum kind: { inter_location: 0, refuel: 1, break: 2 }
  enum driver_acceptance: { pending: 0, accepted: 1, rejected: 2, sent: 3 }


    def paper_trail_events
      changed_fields         = self.changes.keys - ['created_at', 'updated_at']
      self.paper_trail_event = "Updated #{changed_fields.join(',')}"

In Rails Console

> Task.find(1768).versions.map &:event
=> ["Updated start_on,complete_on,status", "Updated worker_id"]


Nano editor Comment/Uncomment in GNU Nano editor using Alt+3 shortcut

GNU Nano editor adjust comment literal for PHP / C / C++

If you are a UNIX lover and fan of Nano text editor then while writing C / C++ code, you would like to put comments using Short-Cut key i.e. Alt+3. But the problem is, Nano puts the char # as comment literal instead of //. This happened because the default literal is # unless it is defined in configurations.

How to fix?

Continue reading

Rails : Spree : Zipcode, phonenumber required false

If you need the shipping address to be set any how, and want to skip the validations as set  in the spree’s address model, you can do it easily

module Spree
  class Address < Spree::Base
    require 'twitter_cldr'

    belongs_to :country, class_name: "Spree::Country"
    belongs_to :state, class_name: "Spree::State"

    has_many :shipments, inverse_of: :address

    validates :firstname, :lastname, :address1, :city, :country, presence: true
    validates :zipcode, presence: true, if: :require_zipcode?
    validates :phone, presence: true, if: :require_phone?

    validate :state_validate, :postal_code_validate


# models/spree/address_decorator.rb
Spree::Address.class_eval do
  def require_phone?

  def require_zipcode?


And you are done

Rails : Customize Rails Admin engine

I wondered what these terms like collection and member mean.

member :activate do
  only ['Contractor']
  i18n_key :activate

collection :painter_photos do
  i18n_key :painter_photos

member: These are actions applicable to individual records in the model. This will show up in every row like.

collection: applicable to the model as a whole

How to add custom action in particular row?

member :activate do
  only ['Contractor']
  i18n_key :activate

for this you would need to put

# in views/rails_admin/main/activate.haml
- if @object.is_a?(Contractor)
  - if @object.active?
    %p Already Activated
  - else
    %p You are about to activate a contractor.
        = @object.full_name
    = link_to "Activate Contractor", main_app.admin_activate_contractor_path(@object), confirm: "Are you sure?", class: "btn"
- else
  %p Sorry, only contractors can be activated.


# in rails_admin.en.yml
  title: "Activate"
  menu: "Activate"
  breadcrumb: "Activate"


Custom Label

field :painters, :boolean do
  label do
    "Send to all contractors"

  render do
    content =  bindings[:form].check_box :painters
    bindings[:view].render inline: content

Customize the Edit / New Form

You can customize the button names in the form but in a tricky way. For example lets try to change the button names like Save to Send and so.

copy the file

https://github.com/sferik/…/_submit_buttons.html.haml this page in your repo at “views/rails_admin/main/_submit_button.html.haml”

and put conditional like

- if params['model_name']  == 'broadcast' && params['action'] == 'new'
  %button.btn.btn-primary{type: "submit", name: "_save", :'data-disable-with' => t("admin.models.broadcast.save")}
    = t('admin.models.broadcast.save')
- else
  %button.btn.btn-primary{type: "submit", name: "_save", :'data-disable-with' => t("admin.form.save")}
    = t("admin.form.save")

and add some i18n keys in rails_admin.en.yml like

    loading: "Loading..."
      name: "Home"
      previous: "&laquo; Prev"
      next: "Next &raquo;"
      truncate: "…"
        save: 'Send Message'
        save_and_add_another: 'Send and prepare for next'
        save_and_edit: 'Send and Edit'

Code Climate : CLI : Custom Analysis Engine : Customize CLI to support your custom engine


Code Climate is a command line interface for the Code Climate analysis platform. It allows you to run Code Climate engines on your local machine inside of Docker containers. After reading this post you will get how to customize the Code Climate CLI to make it support your Analysis Engine. Continue reading

DataTables : Customizing navigation button

var $workflowTable = $('.workflow-table');
      'iDisplayLength': 10,
      'fnDrawCallback': function (oSettings) {
        if (oSettings._iDisplayLength > oSettings.fnRecordsDisplay()) {
        var curPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
        var lastPage = Math.ceil( oSettings.fnRecordsDisplay() / oSettings._iDisplayLength );

        if (curPage === 1){
        if(curPage === lastPage){