Mandrill Dynamic templates – Rails

In this blog post I would be talking about how to create dynamic templates for sending mails to your app users via mandrill templates. I used mandrill-mailer gem, which is a wrapper for mandrill api for sending transnational emails to users. You can see the official doc’s from git-hub to set-up your gem. Before setting up your gem , you need to have a mailchimp account and integrate mandrill with mailchip, for dynamic templates to be created or edited. You can integrate from here the official page of madrill documentation. Once your smtp settings and configurations are set-up for your mail by using the given by mandrill, your all set to go.

Creation of Dynamic Templates:

You can start by creating a template from your mailchimp account which gives you a lot options to customize the templates. Once you have a desired template, after saving it will be listed. Now we need to push this template to your mandrill account so that you can use it for sending mails to your user using the newly created templates. To do this click on the drop down and click on “Send to Mandrill” that’s it, now this template will be available for your use.

Now we need to move to your mandrill account to edit this template, but there is a back door entry from your mailchimp account to do this.

From your mailchimp dashboard click on:

reports > View mandrill reports(top right had corner) > outbound(on dash board) > templates

 

On this page you can see your newly created template from mailchimp or you can create a new one. Now for adding dynamic content to this mail and to be sent to your users you need to add few key words as mentioned by the docs. You need to add a editable section to your created templates so that when we send the content from app it will get place here dynamically.


<div mc:edit="dynamic_content"></div>

After setting this in your template you can send dynamic content from your app.The gem doc mentions about a variable to be set ‘template_content’ along with the call to mandrill template. There you have to mention to which editable tag the content is set for. In the call you also mention the name of the template that will be use for sending to your user. example :

 


mandrill_mail template: 'Template To Test ',
subject: 'Template To Test Notifications',
to: 'abc@idontknow.com',
template_content:{'dynamic_content' => "<span> this is the dynamic content </span>" },
vars: {'LIST_COMPANY' => "xyz" }

 

Using Dynamic Mandrill Template With Device:

Above I have mentioned how to send dynamic templates using mandrill, the same can be done for sending custom templates for device related mails. The doc tells how to write custom mailer templates using rails action mailer, but here I show you how to do using ‘Mandrill-templates’. I guess the code should completely self explanatory.

class CustomMailer < Devise::Mailer
 include MailersHelper
 include Devise::Controllers::UrlHelpers

  def reset_password_instructions (record, token, opts={})
    opts = {
        :template => 'Custom Template On Mandrill',
        :template_content => [
        {
            :name => 'dynamic_activities_content',
            :content => dynamic_mandrill_content_reset_password(record, token)
        }]
    }

    message = {
        :subject=> "Password Reset",
        :from_name=> "XYZ",
        :from_email=>"info@xyz.com",
        :to=>
            [{ "email"=>  record.email}],
        :global_merge_vars => [{"name"=>'MAIL_TITLE', "content"=>"Welcome"}]
    }

    begin
      MANDRILL.messages.send_template opts[:template], opts[:template_content], message

    rescue Mandrill::Error => e
      Rails.logger.debug("#{e.class}: #{e.message}")
      raise

    end
  end
end

That’s it the user user will recieve this dynamic content. Hope this post helps you. Thanks for reading!

Monkey-patching rails Gems (customizing)

In this blog I would like to talk about monkey-patching rails gem, such that opening existing gems class and adding custom methods and using in our application. During development of an app I was faced with a scenario where I needed to add an association to a model from the app and to the model file existing in the gem file. I had achieved this by opening up the class dynamically and adding the association to that required model, and also added few custom methods to it, called these methods in my controller like usual methods.  Let me walk through the steps involved:

The gem that I had monkey-patched was public-acivity. For this gem an ‘activities‘ table gets created. This gem is used for tracking the activities of a user on the site, I had to add an belongs_to association into my to the PublicActivity::Activity‘ model created by the gem. To do this all you have to do is create a intializer file in ‘config/intializers/your_file.rb’ and add the following piece of code and add your custom methods to it:

PublicActivity::Activity.class_eval do

  #attr_accessible [attributes]
  #any other gem methods can also be added
  belongs_to :user, class_name: 'User', foreign_key: :owner_id

  #instance methods
  def my_instance_method
    #do stuff
  end

 #class methods
 def self.my_class_method
   #do stuff
 end
end

and in my user.rb model:

  has_many :user_activities, class_name: "PublicActivity::Activity", foreign_key: :owner_id

Once these changes are done, make sure to restart your server. Now in your controller or models you can access these custom methods:

#class method call
PublicActivity::Activity.my_class_method

#instance method call
pub_act = PublicActivity::Activity.first
pub_act.my_instance_method

#to fetch users activities
current_user.user_activities

This approach helps us to customize any gem according to the needs of our situation. Hope it helped you. Thanks for Reading!

reference:rails docs

Backing-up DB and table specific data and dumping In postgresql(command-line)

There are times when we need to take a database backup from one server to another, the reasons may be due to setting-up a new prod-server, taking a back-up and dumping in the our local end to check for issues or in an intense situation where we had run into some server issues. I have faced such a situation during my development, here I had to migrate the client’s old prod-server to a new-prod server. Let me walk you through the steps that involved in do this.(be sure to test it once on your local-machine before running these commands on the prod-server)

To take a database backup:

postgresql has command to dump the database into a file, if you need to take a specific db back-up you have run this command on your terminal:

pg_dump -h localhost -U {user-name} {source_db} -f {dumpfilename.sql}

example:
pg_dump -h localhost -U postgres   db_to_take_back_up -f file_to_dump.sql

Few things to be noted here, the ‘-h’ option represents the host on which the DB exists, in our case it is localhost(note, if local host throws an error try 127.0.0.1), the ‘-U’ option for user-name of the DB specified(In rails see in your database.yml file), the next option is the database name itself and ‘-f’ option tells it should be dumped into given file name(note the file name extention .sql). The backup file will be created in the current path where you have run the command.

To Restore database:

To restore the db, you need create a new database(see the postgresql docs) from the psql console or you can create from the psql-gui.

Let us assume a database ‘test_backup’ has been created, now let us restore the dump file ‘file_to_dump.sql’ into this newly created database. The command to run on the console is as follows:

psql -U {user-name} -d {desintation_db}-f {dumpfilename.sql}

example:
psql -h localhost -U postgres -d  test_backup_for_sry -f file_to_dump.sql

That’s it the DB is restored!

Moving the files to remote servers:

This command can be used to move the files from your current server to any remote server,

scp  filename.sql   root@(remote server ip):"path to move"

example:
scp  filename_data.sql   root@192.168.x.xxx:"/var/web/myapp/"

Taking Back-up of specific Tables from a database:

There would be times when we need to take back-up of specific tables in our db, here I will show you how to achieve it. I have come across two types of taking the table backup, will explain both of them.

1) As .sql file :

To take a specific table back-up you have to run this command on your console,

pg_dump --table [table-name] -U [user-name] [db-name] -f [file_name.sql]

example:
pg_dump --table coupons -U postgres database_development -f coupons_test.sql

To restore the table into the db,

psql -f table_file.sql [db-name]

example:
psql -f coupons_test.sql single_table_backup_test

2) importing and Exporting as .csv files (importing & exporting)

In the above method I have talked about the normal psql method, we can also take the back-up as csv format file’s, this is a bit longer procedure choose wisely as per our needs.

Let’s assume I need to a take a back-up of a table into a csv format file, for this you need to be in psql console in that respective DB

Exporting:

COPY (SELECT [columns]
FROM table_name
)
TO ['path with file name in .csv extension']

example:

COPY (SELECT gid, name, location
FROM locations
limit 10)
TO '/home/my_app/rails/locations.csv' 

Importing:

When you are trying to import data into PostgreSQL from CSV file, you have to prepare few things before you can execute the COPY FROM query. For the copy query to run successfully, we have to first create a table which is empty from an schema capable of storing the data. A table with similar data-types and columns are required as the back-up file of the table taken.(make sure to have the csv file on the current server your in)

To create a table,

CREATE TABLE temp_table (gid numeric, name character varying(2), location character varying(68))

Once an temp table is created, we can now dump the file which we have into this.

COPY temp_table(gid, name, location)
FROM '/home/my_app/rails/locations.csv'

That’s it you have your temp_table with the data you need, now you can go ahead doing other operations on this.

Hope it helped you. Thanks for Reading!

For more information on back-ups refer postresql docs.

Adding Observers in rails and Skipping them.

In this blog I would like talk about how to implement an observer in rails, this has been removed from rails 4 and can still be achieved using this gem rails-observers found on github. The concept of an observer is similar to that of an callback for the rails models, instead making it specific callback to a model we can generate a generic callback. This would reduce the amount of code to be written also, and can be achieved using ‘observers’ in rails. Observers needs to be implemented according to the situation in hand, there is no point in adding an single observer for a task that be achieved using a callback for the life cycle of an object. The idea behind implementing an observer is that if a common function needs to be executed for many classes during the objects life-cycle,  a common scenario that can be used in implementing the observer is that if an email is to be fired to the user after creation of records in certain models, observer is a best choice to opt for. The observers have hook_methods similar to the callbacks like like ‘after_save’,’before_save’ … etc (see this link for more details)In this blog i’m going take a little bit more complex example that I had encountered during my development.

In my development, we were using the gem public_activity which records the activities of the users on the site. I had a scenario in hand for which the system had to create an entry in gem created table ‘PublicActivity::Activity’  for creation of new objects of few specified models.

To create a new activity_observer, in the console run

$ rails generate observer Activity

this will generate a file activity_observer.rb under app/models/activity_observer.rb  containing the observer class ActivityObserver. (It is always better if the observers are kept in a folder specific for them, I had created a folder under app/observers/activity_observer.rb )

To Register an Observer in the application:

Once after an observer is created we need to register it. This can be done by setting a line in ‘config/application.rb‘ file.

config.active_record.observers = :activity_observer

Adding functions in the observer: 

I needed to create a record in the activity table after creation of a object. So in my activity observer the changes done were,

class ActivityObserver < ActiveRecord::Observer
  observe :user, :gallery, :profile
  def after_create model
    case model.class.name
      when "User"
        #do stuff
      when "Gallery"
        #do stuff
      when "Profile"
        #do stuff
    end
  end
end

Now our observers are setup, on creation of any new objects for the models, an entry in the public_activity table will be created.

Skipping Observers:

There are certain situations in your application for which we need to disable the observer. An observer can be disabled for a brief duration of the block. For the above observer created let us disable the observer for creation of the gallery. The code for this is below

Gallery.observers.disable :activity_observer do
  # all gallery observers are disabled for
  # just the duration of the block
  gallery = Gallery.new({:name => 'test', :location => 'CA'})
  gallery.save!
end

and that’s it the gallery observer in activity observer will be disabled for the duration of the block only.

Hope it helped you, Thanks for reading!

reference:rails docs

Rails ActiveRecord Data Serialize

Recently I ran into a problem in my application where I had to store multiple Boolean values in the DB. There  are many ways to do this, but I wanted to implement it in the most efficient way. One of the method  is create that many number of specific columns in your table store the data, but for that we had to create ‘n’ of columns in the db which was not a promising solution.

On digging a little more deeper, I found out that hashes can be stored in a single column of a database, this is known as “Serialization” in rails. I had this implemented in my app which was simple and elegant to store my data as hash, and the retrieving of the data was also much more simpler. In my case I needed to have three Boolean fields stored in a hash under a single column in the DB. Let me walk you through the steps as in how I implemented it.

I Had model ‘user.rb‘ to which I needed to add a column ‘:boarding_skip_steps_status‘, for this I generated a migration file with a text field. This is how my migration file looks:

class AddOnBoardingStatusToUsers < ActiveRecord::Migration
 def change
  add_column :users, :boarding_skip_steps_status, :text, :default => {:facebook => false, :follow   => false, :travelogue => false}.to_yaml

  User.update_all(["boarding_skip_steps_status = ?", {:facebook => false, :follow => false,   :travelogue => false}.to_yaml])
 end
end

Let me explain what is being done here, I’m adding a column to the users table and setting it to default. You can notice the use of “to_yaml” method being used,  the reason is that when rails stores an hash value in the DB it converts the hash to YAML format. The line of code updates your existing users with the defaulted hash.

In your User model, add the line,

serialize :boarding_skip_steps_status
attr_accessible :boarding_skip_steps_status

and that’s it, now you can store and retrive the values just like your normal any other attributes in the object.

See the below O/P:

To Store Data:

=> u= User.find(22)
=> u.boarding_skip_steps_status = {:facebook=>true, :follow=>true, :travelogue=>false}
=> u.save

To retrieve the data:

=> U = User.find(22)
=> <#User id: 22, email: "abc@gmail.com",  created_at: "2014-09-25 06:41:46", updated_at: "2014-10-11 13:19:49", on_boarding_status: false, boarding_skip_steps_status: {:facebook=>true, :follow=>true, :travelogue=>false}>
=> U.boarding_skip_steps_status
=> {:facebook=>true, :follow=>true, :travelogue=>false}
=> U.boarding_skip_steps_status[:facebook]
=> true

To update data:

=> U.boarding_skip_steps_status[:facebook] = false
=> U.save

Thats all  an hash of data is stored in the DB, hope it helps you!

Thanks For Reading!

reference:apidock rails.

Nested has_many :through Relationships In Rails

The Rails  association convention for many-to-many relationships give us an easier way to fetch data from DB and also join the models. A user has many groups through memberships, when association is specified for a user in the model properly, we can easily access for a user’s groups without having to go to memberships table then access groups. Now lets say we want to access the list of meetings for a user, and assume that Group model has_many meetings w.r.t associations, now if we want to access the meetings list we would have to get the groups w.r.t user and loop it to access the meeting associated with the user, which is a longer way. This can be achieved  in another way mentioned below using nested has_many :through() relationships,

models/user.rb
class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, :through => :memberships
end
models/membership.rb
class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
end

models/group.rb
class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, :through => :memberships
  has_many :meetings
end

models/meeting.rb
class Meeting < ActiveRecord::Base
end

To get access to a given user’s meetings, we would have to fetch the user’s groups and then loop through it fetching the group’s meetings. This is would not be a efficient way. for example,

  user = User.first
  groups = user.groups
  groups.each do |group|
    #do stuff
  end

As we loop through the groups, fetching meetings we are making a separate query for each group which is not good. What if we had hundreds of groups to loop through. Why dont we do it something like ” User.meetings” ?

models/user.rb
class User < ActiveRecord::Base
  has_many :memberships
  has_many :groups, :through => :memberships
  has_many :meetings, :through => :groups
end

We have added one more line to the association, and that is it, this would fetch the corresponding data.

user = User.first
user.meetings

Thanks For Reading!

reference:rails guides on associations

Rails Security – Hiding sensitive Information

There is a time when we often run into a situation where we have keep some secret keys or credentials like payment gateway api key’s or any such secret keys for that matter, we often would go for hard coding and placing them in conf files, but problem is that when we push this to a remote repository all the credentials will be publicly seen by others, there may be times when want to to keep some info which is very private to us or the app. We can set them as environmental variables , If you set them as env variables they will be set on your environment(os) level that your application can access, but not mentioned in the application level.This way, your secrets stay secret from public eyes.

Recently I had run into a situation in the application I was working on to find a way to hide these variables, on doing a research, I found out that there are ways to do at the bash level. This method does not suit always, you can store the environment variable key/value pairs with the operating system directly , so they will be accessible to the Rails app. In your .bashrc file or zshrc file, place the environment variables as shown below:

export Key = Value

With this, you can fire up rails console or irb and access your environment var by doing:

ENV["Key"]
"Value"

This method does not suit every time, this leads to lot of complications.

The Gem Approach(which was ideal) :

After doing a search for a while, that’s when I came across “Figaro”, a rails gem which does the job perfectly for the above mentioned problem. This is very straight forward gem, after installing you can store in a YAML file at config/application.yml. To create the YAML file we have run the command

$ figaro install

This creates a commented config/application.yml file and adds it to your .gitignore. And that’s it you mention your the sensitive data in this and git will ignore it. Using this file you can set variables for different ENV.

While deploying the application on heroku,  figaro  makes it simpler for us. Using the figaro command, you can set values from your configuration file all at once:

$ figaro heroku:set -e production

There are other gems that are available like “dotenv”, have a look at this too.  Hope this blog helped you.

Thanks for Reading !

Integration Of Canvas-Pop API (push & loader calls)

Recently I had to implement the canvas-pop store api in the application that i’m currently working on, in rails. Since there was no proper docs or gems provided for this api apart from the one that is avaliable on the site’s documentation. On the site they have mentioned only for pull api call and no where it was mentioned about the ‘push’ and ‘loader’ api methods. This took quite a while for me to implement, let me walk through the steps. This implementation was done in rails.

The site mentions about a two-step and three-step handshake image-process, here I’ll implement a two-step handshake.

step 1:

“Complete a single image handshake using the /api/push/image endpoint and receive an image_token value”

For this step I had used ‘httpclient’ gem to interact with the api server, to get the image token.

#file to be in binary format.
file_path = Rails.root.join('app', 'assets', 'images', 'tmp_cp').join(params[:file_s3_name])
s3client = s3
File.open(file_path , 'wb') do |f|
  f.write(s3client.buckets[ENV["AWS_S3_BUCKET"]].objects[params[:url].split("amazonaws.com/")  [1]].read )
  f.close
end

#store call for image_token
uri = "https://store.canvaspop.com/api/push/image"
header = [["CP-Authorization", "basic"],["CP-ApiKey", ENV["CP_API_KEY"]]]
file_path = Rails.root.join('app', 'assets', 'images', 'tmp_cp').join(params[:file_s3_name])
image = File.open(file_path ,'r+b')
body = { 'upload' => image }
clnt = HTTPClient.new()

#actual call
begin
  res = clnt.request("POST", uri, nil , body, header)
  @image.update_attributes(:image_token => ((res.body.split(":")[1].split(",")[0]).gsub  /"/, ''))
rescue Exception => e
  #do nothing
end

#response
res = (res.blank? || res.body.blank?) ? "false_cp" : ((res.body.split(":")[1].split(",")[0]).gsub /"/, '')
File.delete(file_path) #delete the temp image file
image.close

Explanation:

– The server expects the request to contain the “CP-Authorization” and “CP-ApiKey” to be present in the request headers, for rails place it in the config/environment.rb file. To get the cp-api key see the site for details.

– The server even expects the image to be in binary format, that is why we read the source file and write it as binary one and save it temporarily.

– Once the call is made, if it is successful an image_token in json format will be returned.

Step 2:

“Open Pop-up Store using the /loader endpoint including the image_token received”

Once the token is recieved, use it to open the store front, I used an ajax call and a pop-up modal to achieve this.

var page = "https://store.canvaspop.com/loader/" + token;

Once done you can use their push message implementation as suggested in the docs to receive the event message at our end and manipulate it to our needs.

Thanks For Reading !