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"]



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'

Rails : Stripe : Handle 14 days Trial subscriptions

What happens when Trial Period Ends

the customer.subscriptions.trial_will_end event fires 3 days before a trial ends.

When the trial period ends, there will be a customer.subscription.updated event and an invoice.created event. An hour (or so) later, you’ll then either see an invoice.payment_succeeded event or an invoice.payment_failed event. From those, you’ll know whether the payment went through or not.

Continue reading