Notes posted by rubyonrailsdevelopment
RSS feedUpload Files Directly To S3 Using Paperclip And Dropzone.js
Upload Files Directly To S3 Using Paperclip And Dropzone.js
by | Dec 22, 2017 | Technical Articles | 0 comments
It’s usually the small time-consuming tasks that frustrate us the most. Such as uploading a file to S3; the requirement is pretty simple but the method chosen to upload the file will decide the efficiency of the task. As uploading files is a feature that most applications require, RailsCarma has compiled a brief tutorial on one of the best methods of getting this task done efficiently: using Paperclip and Dropzone.js.
Paperclip is a popular choice for uploading images and files as it offers great features to handle the attachments; ‘paperclip’ gem is the go-to option. Paperclip allows you to upload multiple images and files, generate thumbnails and even automatically resize the images. It boasts of a large and active community making it the top choice of most developers. Dropzone.js is an open source library with file drag & drop (with image preview) features. Amazon S3 is a simple storage device for data storage. We can use it to retrieve images and all type of files.
Why Paperclip?
Paperclip is a popular file uploading tool for the following reasons:
Supports File Caching: If a form fails to validate, we don’t want the user to pick his file again and re-upload it. Therefore, file caching is necessary from a UX standpoint. And it also conserves the bandwidth. Processes Images Paperclip is able to resize and crop images to several different formats thus allowing the developer to choose the library. Simplifies The Task! Paperclip gem does not pollute your code and is easy to test! Allows File Processing Paperclip allows file processing for EXIF data extraction and thumbnail creation of uploaded PDFs, PSDs, DOCs, XLSXs. Provides CDN & Storage-Service Support This is a big plus as we want to keep the bandwidth to our servers as low as possible and avoid possible data loss due to server failure. Offers On-The-Fly Processing Paperclip processes images and files on a per-request basis. This is an innovative feature that enables developers to create custom content that adapts best to different situations.
What Are The Dropzone Asynchronous Events?
addedfile: When a file is added to the list. removedfile: Used whenever a file is removed from the list. You can listen to this and delete the file from your server if you want to. thumbnail: When the thumbnail has been generated. It receives the data URL as second parameter. error: An error occurred receives the error message as the second parameter. And if the error was due to xmlhttprequest, the xhr object is received as the third parameter. processing: When a file is processed (since there is a queue, not all files are processed immediately). This event was previously called processingfile. drop: The user dropped something onto the drop zone.
How Can We Configure Paperclip In Our Application?
has_attached _file: asset :storage => :s3 :S3_host_name => ENV[“S3_HOST_NAME”] :S3_region => ENV[“S3_REGION”] :S3_protocol => ENV[“S3_PROTOCOL”] :path => “:account_id/:class/:source_id/:attachment/:file_name”,:s3_headers => {‘ContentDisposition’ => ‘attachment’, ‘content-type’ =>‘application/octet_stream’}, :bucket => ENV[“S3_BUCKET”], :s3_credentials => Proc.new{|a| a.instance.s3_credentials} Do_not_validate_attachment_file_type :asset def s3_credentials {:access_key_id => ENV[“S3_ACCESS_KEY_ID”], :secret_access_key => ENV[“S3_SECRET_ACCESS_KEY”]} end
How Can We Handle Custom Paths In Our Application? Read More from here http://www.railscarma.com/blog/technical-articles/upload-files-directly-s3-using-paperclip-dropzone-js/
Urlify Functions & Its Implementation
URLify is a simple gem that refines the conversion of UTF-8 strings to ASCII-safe URI strings and enables it to be used as readable URL-segments. After the gem is installed, you can call the URLify function for any UTF-8 string and it will be automatically converted into an ASCII-safe URI string. URLify also has the additional functionality of being able to remove the subtitles in a given input. ACCENTMAP
‘À’ => ‘A’, ‘Á’ => ‘A’, ‘Â’ => ‘A’, ‘Ã’ => ‘A’, ‘Ä’ => ‘A’, ‘Å’ => ‘AA’, ‘Æ’ => ‘AE’, ‘Ç’ => ‘C’, ‘È’ => ‘E’, ‘É’ => ‘E’, ‘Ê’ => ‘E’, ‘Ë’ => ‘E’, ‘Ì’ => ‘I’, ‘Í’ => ‘I’, ‘Î’ => ‘I’, ‘Ï’ => ‘I’, ‘Ð’ => ‘D’, ‘Ł’ => ‘L’, ‘Ñ’ => ‘N’, ‘Ò’ => ‘O’, ‘Ó’ => ‘O’, ‘Ô’ => ‘O’, ‘Õ’ => ‘O’, ‘Ö’ => ‘O’, ‘Ø’ => ‘OE’, ‘Ù’ => ‘U’, ‘Ú’ => ‘U’, ‘Ü’ => ‘U’, ‘Û’ => ‘U’, ‘Ý’ => ‘Y’, ‘Þ’ => ‘Th’, ‘ß’ => ‘ss’, ‘à’ => ‘a’, ‘á’ => ‘a’, ‘â’ => ‘a’, ‘ã’ => ‘a’, ‘ä’ => ‘a’, ‘å’ => ‘aa’, ‘æ’ => ‘ae’, ‘ç’ => ‘c’, ‘è’ => ‘e’, ‘é’ => ‘e’, ‘ê’ => ‘e’, ‘ë’ => ‘e’, ‘ì’ => ‘i’, ‘í’ => ‘i’, ‘î’ => ‘i’, ‘ï’ => ‘i’, ‘ð’ => ‘d’, ‘ł’ => ‘l’, ‘ñ’ => ‘n’, ‘ń’ => ‘n’, ‘ò’ => ‘o’, ‘ó’ => ‘o’, ‘ô’ => ‘o’, ‘õ’ => ‘o’, ‘ō’ => ‘o’, ‘ö’ => ‘o’, ‘ø’ => ‘oe’, ‘ś’ => ‘s’, ‘ù’ => ‘u’, ‘ú’ => ‘u’, ‘û’ => ‘u’, ‘ū’ => ‘u’, ‘ü’ => ‘u’, ‘ý’ => ‘y’, ‘þ’ => ‘th’, ‘ÿ’ => ‘y’, ‘ż’ => ‘z’, ‘Œ’ => ‘OE’, ‘œ’ => ‘oe’, ‘&’ => ‘and’
Easy Steps To Implement URLify Gem
Go to the Gemfile and add the gem urlify Run the command bundle install
OR In the terminal, run the command gem install urlify A Demo Of Implementation Of URLify
Here is an example of URLify functionality:
Add gem urlify in your Gemfile Run bundle install
Read More From Here http://www.railscarma.com/blog/technical-articles/urlify-functions-implementation/
PAGER DUTY & EXCEPTION NOTIFIER PLUGINS FOR RAILS
RAILS EXCEPTION NOTIFIER
The Exception Notifier plugin provides a mailer object and a default set of templates for sending email notifications when errors occur in a Rails application. It is basically a monitoring tool, which keeps on watching the application and whenever it finds any error, it triggers that error to PagerDuty. To use Exception Notification and PagerDuty in your app, you need to add this gem below:
gem 'exception_notification', '~> 4.1.0' gem 'pagerduty''
To get the email notifications, you need to include the line below in the development env:
Rails.application.config.middleware.use ExceptionNotification::Rack, :email => { :email_prefix => "[PREFIX] ", :sender_address => %{"notifier" <notifier@example.com>}, :exception_recipients => %w{exceptions@example.com}, :pd => { # simple notifier options } }
You can modify sender’s and recipient’s address.
Rails App+PagerDuty
Use the code below in your app with exception notifier to connect with PagerDuty:
require "pagerduty" module ExceptionNotifier Class PdNotifier def initialize(options) @pagerduty = Pagerduty.new("0bdcfdacf1b144d7822dfdfa5ed0ab1e")# Service api key # do something with the options... end def call(exception, options={}) @pagerduty.trigger(exception.message, details: { backtrace: exception.backtrace }) end end end
Conclusion
PagerDuty is alert dispatching tool used by operations team/OnCall Engineers to manage the applications and it is popular because of its reliable & rich services(Scheduling,Alerting,Reporting,Call Routing , Feedback & response time).
Create your Free account from app.pagerduty.com/ and integrate with your application to get the flow , how Incident is triggered.
How to use Textacular Gem to search data in your Rails Application
We might have heard about a lot many gems which let us implement search functionality in our rails application; for example: searchkick, elasticsearch-rails, ransack and finally, sunspot to work with solr search engine. All these gems have their own advantages. Both searchkick and elasticsearch use redis to search the data as well as need to perform a ‘reindex’ while inserting new data. In one of my recent projects, I happened to use a gem called as Textacular. It’s simple and very easy to use. Textacular Gem:
It is a gem that provides full text search capabilities for PostgreSQL Database. It basically caters to extend the scope of the work performed by activerecord, in a rather friendly manner. It works on heroku as well. This gem works only on PostgreSQL For working with it, let’s first grab the latest textacular gem from rubygems.org/gems/textacular and add it to the gemfile.
gem 'textacular' bundle install
Textacular gem provides us with quite a few methods to search the data. So, all our models have the access to use those methods.
basic_search advanced_search fuzzy_search
Usage: Basic_search: It searches based on the input text.
User.basic_search(‘abc’) # Searches on all the model column attributes User.basic_search(last_name: 'abc', first_name: 'xyz')
Advanced_search: Here, we can use postgres syntaxes like !, & and | (and, or and, not) and then, some others based on the requirement. It converts user’s search DSL into Pg syntax. For this, we need to make sure that the necessary exceptions should be used to handle the syntax errors.
User.advanced_search(last_name: 'text1|text2’) - It searches with the text1 or text2 on last_name on User model.
User.advanced_search(last_name: '!text2’) - It searches for the records whose last_name is not text2.
These searches can be chainable as shown below:
User.advanced_search(last_name: 'text1|text2’).basic_search(last_name: 'abc', first_name: 'xyz')
Fuzzy_search: We need to install pg_trgm module to work with fuzzy_search. Run the command below to install this module. It searches for partial appearance of your text in the DB.
rake textacular:create_trigram_migration rake db:migrate
Now, we are ready to use fuzzy_search.
User.fuzzy_search('Lorem')
By default, fuzzy search, searches for the records which are 30% of the search text matches with respect to the entire content. We can set this threshold limit by using the command below.
ActiveRecord::Base.connection.execute("SELECT set_limit(0.6);")
So, it expects 60% of search text to match with the original content. We can use OR condition to search on multiple columns. Need to pass a hash with columns with input text as param one and pass second param as a false. It takes AND, if you miss second param or if it True.
User.fuzzy_search({first_name: 'user', last_name: 'test'}, false) User.fuzzy_search(first_name: ‘user’, last_name: 'test') - It takes AND condition.
By default, the Textacular searches in all text and string columns. We can alter its default behaviour by overriding the searchable_columns method in the model.
def self.searchable_columns [:title, :body] end
We can override self.searchable_language in the model to set proper dictionary settings.
def self.searchable_language 'arabic' end
Faker Gem: Fake Data Generation in Ruby
Gems are libraries in Rails that generally enable you to write the application code faster and thereby making a great product in far lesser time. Usually, whenever we start developing any application, there comes a point when we need data which we can use to see how the application will behave while doing some load testing or how it would look when we deploy it to the production. The manual process of creating the data can be daunting. Faker gem serves to take this pain away by generating the fake data just as needed and saving us all the time and effort otherwise wasted in the manual process of data-generation.
It can generate almost any kind of data suitable for our application. For example, it can generate the fake data for fields such as name, email, passwords, phone-numbers, paragraphs, etc. It is therefore, an awesome way of populating the model (which is a database layer in Rails)
Let’s take a look at this gem by creating a sample project. Read More: http://www.railscarma.com/blog/technical-articles/faker-gem-fake-data-generation-ruby/
Converting Hash to Struct in Ruby
With the fact we know about the two, many will perhaps prefer using struct rather than hash. But what we want to focus here is that behind the low performance given by hash, they still can become advantageous. If you can’t use it on its own little way, then convert it into struct so better usability can be achieved.
If you have already defined the struct and you wanted to initiate converting hash to struct, we can help you by using the following methods in a given example below. If you wanted to convert has to a struct in Ruby, let us say for example we have a given of:
h = { :a => 1, :b => 2 }
and want to have a struct such as:
s.a == 1 s.b == 2
To convert, you can do any of these methods: Conversion Method 1:
On this method, the result will appear to be OpenStruct and not specifically as struct:
pry(main)> require 'ostruct' pry(main)> s = OpenStruct.new(h) => #<OpenStruct a=1, b=2> pry(main)> puts s.a, s.b
Conversion Method 2:
If you have struct defined already and want to start something with a hash, you can follow this:
Person = Struct.new(:first_name, :last_name, :age) person_hash = { first_name: "Foo", last_name: "Bar", age: 29 } person = Person.new(*person_hash.values_at(*Person.members)) => #<struct Person first_name="Foo", last_name="Bar", age=29>
Conversion Method 3:
Since the hash key order was guaranteed in the Ruby 1.9+, you can follow this:
s = Struct.new(*(k = h.keys)).new(*h.values_at(*k))
The hash to struct conversion example we provided can help, but if you want a more extensive idea, come to professionals for formal assistance. Read More From Here http://www.railscarma.com/blog/technical-articles/guide-converting-hash-struct-ruby/
How to use belongs_to in Ruby on Rails
Rails 4: Let’s assume we have two models Movie and Actor. Actor has many movies and Movie belongs to Actor. In most of the cases, the developers used to validate the foreign key actor_id is present or not. In this case, it will not validate actor model as to whether the entered actor id exists or not. It is just like attribute validation which always validates that the fields should be non-empty when submitting the form.
Validation with foreign key: class Movie < ApplicationRecord belongs_to :actor validates :actor_id, presence: true end
class Movie < ApplicationRecord belongs_to :actor validates :actor_id, presence: true end class Actor < ApplicationRecord has_many :movies, dependent: :destroy end
class Actor < ApplicationRecord has_many :movies, dependent: :destroy end
The scenario above, validates actor id presence or not like normal attribute presence validator.
Ex: Actor.create(title: “abc”). => {id: 1, title: 'abc'} m = Movie.new(title: “ok ok”, actor_id: 111) => m.valid? => true => Actor.find(111) ActiveRecord::RecordNotFound: Couldn't find Actor with 'id'=111 Ex: Actor.create(title: “abc”). => {id: 1, title: 'abc'} m = Movie.new(title: “ok ok”, actor_id: 111) => m.valid? => true => Actor.find(111) ActiveRecord::RecordNotFound: Couldn't find Actor with 'id'=111
We can still save the movie record without valid actor.
With associations
class Movie < ApplicationRecord belongs_to :actor validates :actor, presence: true end
class Movie < ApplicationRecord belongs_to :actor validates :actor, presence: true end
(or)
class Movie < ApplicationRecord belongs_to :actor, required: true end
class Movie < ApplicationRecord belongs_to :actor, required: true end class Actor < ApplicationRecord has_many :movies, dependent: :destroy end
class Actor < ApplicationRecord has_many :movies, dependent: :destroy end Ex: Actor.create(title: “abc”). ==> {id: 1, title: 'abc'} m = Movie.new(title: “ok ok”, actor_id: 111) ==> m.valid? => false ==> m.errors.full_messages, ['Actor can't be blank']
Ex: Actor.create(title: “abc”). ==> {id: 1, title: 'abc'} m = Movie.new(title: “ok ok”, actor_id: 111) ==> m.valid? => false ==> m.errors.full_messages, ['Actor can't be blank']
In this case, it will always validate whether the entered actor exists or not. In case of an invalid actor it throws error to you. This is the best practise to make your associations. It always checks for the associated object exists or not.
Rails5 From rails5 these validations were added by default. It validates association object should be present when you define belongs_to associations.
Release notes http://guides.rubyonrails.org/5_0_release_notes.html(belongs_to will now trigger a validation error by default if the association is not present.)
We can opt out of this feature completely from the application by setting config opton in initializer file.
config/initializers/new_framework_defaults.rb
config/initializers/new_framework_defaults.rb
Rails.application.config.active_record.belongs_to_required_by_default = false Rails.application.config.active_record.belongs_to_required_by_default = false
This initializer file is present in rails5 application only. Need to add this initializer file manually when you migrate from older version of your rails application and make necessary changes.
class Post < ApplicationRecord has_many :comments, dependent: :destroy end
class Post < ApplicationRecord has_many :comments, dependent: :destroy end class Comment < ApplicationRecord belongs_to :post end class Comment < ApplicationRecord belongs_to :post end c = Comment.create(title: “awesome post”) c.errors.full_messages.to_sentence => “Post must exist”
c = Comment.create(title: “awesome post”) c.errors.full_messages.to_sentence => “Post must exist”
We can not create any comment record without an associated record.
We can opt out this default behaviour by setting
belongs_to :post, optional: true belongs_to :post, optional: true c = Comment.create(title: “awesome post”) c = Comment.create(title: “awesome post”) => <Comment id: 1, title: “awesome post”, post_id: nil>
http://www.railscarma.com/blog/technical-articles/use-belongs_to-ruby-rails/
Rails caching with dalli gem
Dalli is a high performance pure Ruby client for accessing memcached servers. It works with memcached 1.4+ only, as it uses the newer binary protocol.
Memcache Memcached is a quick in-memory protest reserving framework that can make Rails run much quicker with not very many changes. Memcached is an in-memory key-value store for little pieces of discretionary information (strings, objects) from consequences of database calls, API calls, or page rendering.
Run the command below to install memcached On Ubuntu
sudo apt-get install memcached
On Mac
brew install memcached
Please refer the URL below to know more about installing memcahed
https://github.com/petergoldstein/dalli#installation-and-usage Install dalli gem gem 'dalli'
Add the gem above to your gemfile and run bundle install.
Configuration Here, we have to configure our rails app to serve caching mechanisam. Add below line to the production.rb(config/environments/production.rb)
config.cache_store = :dalli_store Dalli::Client accepts the following options. All times are in seconds.
expires_in: Global default for key TTL. Default is 0, which means no expiry. namespace: By default, it is nil. It’s prepend to each key if you specify namespace. failover: Default is true. Boolean, if true, Dalli will failover to another working server if the main server for a key is down. threadsafe: Boolean. If true, Dalli ensures that only one thread is using a socket at a specified given time. Default is true. serializer: The serializer to use for objects being stored (ex. JSON). Default is Marshal. compress: Boolean, if true Dalli will gzip-compress values larger than 1K. Default is false. compression_min_size: Minimum value byte size for which to attempt compression. Default is 1K. compression_max_size: Maximum value byte size for which to attempt compression. Default is unlimited. Please check more configations at
https://github.com/petergoldstein/dalli#configuration
After this, we have to tell ActionController to perform caching. Add the line below to the same file and restart Rails server if you are already running it.
config.action_controller.perform_caching = true
Please add the code below to your index method
@posts = Rails.cache.fetch('posts', expires_in: 5.minutes){ Post.all }
Here, Rails.catche.fetch reads the data from ‘posts’ key. If the specified key has any data, it will return data otherwise it will write to that key and it will be available for successive calls within the expiry time.
Rails provides helpers such as Rails.cache.read to read the cache, Rails.cache.write to write in the cache and Rails.cache.fetch to return the results if present in the cache or else, write in the cache to return the results.
You can read more about Rails cache at
http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html Rails.cache.clear() – Flushing all the keys from memcached. Rails.cache.delete(‘posts’) – If you wish to flush any specific key from memcached server.
http://www.railscarma.com/blog/technical-articles/rails-caching-dalli-gem/
Code Refactoring Gem – Flay
Flay examines code for structural likenesses. Differences in literal values, variable, class, method names, whitespace, programming style, braces vs do/end, props versus do/end, and so forth are all overlooked,making this absolutely rad. It’s fit for recognizing both correct and close matches, and does in certainty discover a few spots in Active Record where patterns repeat. In its current state, Flay’s output is very primitive: a list of repeated code nodes, together with a weight to rank them by and line numbers and file names where the repeated code appears. Code that flay reports as comparative is a decent possibility tool for refactoring.
Command to install
sudo gem install flay
Command to see output
Cd “Path to your project folder” flay “path of the folder” Eg : flay ./app/controllers - Identifies the code duplication in all the controllers. flay ./app - Identifies the code duplication in entire project flay ./app/controllers/example_controler.rb - Identifies the code duplication in specified controller.
Example of Output An output is generated of the code duplicated areas like this:
sridevi@carmatec-MS-7788$ flay ./app/models/*.rb Total score (lower is better) = 1666 1) Similar code found in :call (mass = 170) ./app/models/example.rb:8 ./app/models/example.rb:9 ./app/models/example.rb:10 ./app/models/example.rb:11 ./app/models/example.rb:15 ./app/models/example.rb:17 ./app/models/example.rb:19 ./app/models/example.rb:20 ./app/models/example.rb:22 ./app/models/example.rb:23 2) Similar code found in :defs (mass = 154) ./app/models/example.rb:260 ./app/models/result.rb:195 3) Similar code found in :defs (mass = 138) ./app/models/feedback.rb:62 ./app/models/example.rb:54 ./app/models/result.rb:51 4) Similar code found in :call (mass = 136) ./app/models/example.rb:12 ./app/models/example.rb:13 ./app/models/example.rb:14 ./app/models/example.rb:16 ./app/models/example.rb:18 ./app/models/example.rb:21 ./app/models/example.rb:24 ./app/models/example.rb:25 5) IDENTICAL code found in :defn (mass*2 = 128) ./app/models/result.rb:7 ./app/models/summary_report.rb:7 6) IDENTICAL code found in :defn (mass*2 = 120) ./app/models/example.rb:17 ./app/models/example.rb:23
The total app score of 1666 (‘lower is better’ advice holds true) can be viewed in its individual components showing areas that provide the most bang for the buck. For experienced developers operating on their own or in a small team Flay may be unnecessary. However, on larger projects (as the one I ran it on) or those with beginner or intermediate programmers it can help increase the maintainability of your codebase. http://www.railscarma.com/blog/technical-articles/code-refactoring-gem-flay/
Track Changes To Your Model’s Data with Paper Trail Gem
Paper trail lets us track all the changes in the models data for the purpose of its editing and versioning. By using this gem, we can see how a model looks, at every stage of its life-cycle and we can take it back to any version of the model data and we can even undo all the changes after a record has been destroyed so as to restore it completely.
gem ‘paper_trail’ run bundle install to install it
After bundle install you can run the following command for adding versions table to your database
bundle exec rails generate paper_trail:install bundle exec rake db:migrate Add has_paper_trail method to your models for tracking. class Product < ActiveRecord::Base has_paper_trail
end
If you are using a current_user method then you can track who is responsible for particular change by the below callback
class ApplicationController
before_action :set_paper_trail_whodunnit end
Features of paper trail gem
It stores each and every change happened in the model like create, update and destroy It does not store any updates unless if any modifications It allows you to get every version including the actual and even once destroyed
Basic Usage
Now you have a versions method which returns all the changes in particular model
product = Product.find 2
product.versions
# [<PaperTrail::Version>, <PaperTrail::Version>, ...]
Based on the vesrion you can find the changes that happened in a model
v = product.versions.last v.event # it returns update / create / destroy v.whodunnit #it returns a user id who did this v.reify the poduct as it was before the update
you can navigate versions by using previous_version and next_version methods
product = product.previous_version product = product.next_version #it returns nil if there is no object product.versions.last.whodunnit #it returns the user who did the particular change
For More Read From Here : http://www.railscarma.com/blog/technical-articles/track-changes-models-data-paper-trail-gem/
Ruby Developers
How to create a Ruby Gem Ruby Gems or “gem” is a package manager for the Ruby programming language that provides a standard format for distributing Ruby programs and libraries. It is easy to manage and install to your system and it can be used by various rails applications development.
Every RoR developer might have customised a gem at least once in his career, but not each one of them has actually, created a gem. Here, I am going to give a basic idea about how to create a new gem and how to publish it.
Kick off Before starting please make sure that you are using the latest ruby version. RVM is really useful in this case;
How to name your Gem Don’t blindly give a random name to your gem. Please take care of the following; Every dash represents a structure (folder, module) immersion Every underscore represents a joining in the class name
Some examples:
gem new_test_gem require ‘new_test_gem’ module/class NewTestGem
gem gem-structure-new_test_gem require ‘gem/structure/new_test_gem module/class Gem::Structure::NewTestGem
How to create your Gem To create a gem; $ bundle gem new_test_gem It will create some basic files and directories.
Where to add your code or job Your beautiful code goes here
# lib/new_test_gem.rb
Once you have added your code into the lib file then you will have to update the gemspec file;
# new_test_gem.gemspec
For Complete details go through this link => http://www.railscarma.com/blog/technical-articles/how-to-create-a-ruby-gem/
Ways of Handling PayPal Refunds in Rails
PayPal Checkout includes payment solutions ranging from simple to robust that let the merchants as well as developers choose an integration option that can be the best-suited for their website and customers. In order to integrate Paypal Payment Gateway, we need to do the following:
-
Have a PayPal business or Premier account.
-
Create a PayPal app and get an access token. When we create a PayPal app, PayPal generates a set of OAuth client_id and secret keys for the application. PayPal generates these keys for both the PayPal sandbox and Live environments. To get an access token, pass the client-id:secret credentials in the Authorization header. We use the access token for authentication when we make REST API requests.
-
To perform an end-to-end test of our Express Checkout with In-Context integration, create both merchant and buyer accounts in the PayPal sandbox environment.
www.sandbox.paypal.com/in/webapps/mpp/home Merchant : Select the Business account type and enter an email address and password. Buyer : Select the Personal account type and enter a high PayPal balance, such as 5000.
Once we create Paypal sandbox account then click on the “Profile” link for that account, look under the tab “API Credentials”. We will have the following information;
Paypal API Username Paypal API Signature Paypal API Password
Note: When we are ready to go live we would just use the credentials from our real paypal account instead of the ones from our sandbox account. The credentials can be found in the “My Profile” area under the left hand tab “My Selling Tools” under the option “API access”
How to handle Paypal refunds in Rails:
Method 1:
Paypal Rest API;
For more complex merchant sites, direct calls to PayPal APIs for an Express Checkout integration may be a more appropriate integration. REST APIs — We can develop an Express Checkout integration using PayPal REST APIs.
To integrate the Express Checkout with In-Context flow; developer.paypal.com/docs/api/ OR PayPal REST API Ruby SDK (paypal-sdk-rest gem): The PayPal REST SDK provides Ruby APIs to create, process and manage payment.
Installation: Add the gem our application, in Gemfile:
gem 'paypal-sdk-rest'
And then execute:
$ bundle install
rails g paypal:sdk:install
Refunds a transaction: Any transaction we can issue a refund (Both direct and captured payments):
Refund a completed direct payment (sale) Refund an authorized and captured payment (capture)
Refund a completed payment (sale): If we must refund a completed payment, or sale, provide the sale id given to us in response to a completed payment along with an empty JSON payload for a full refund and for partial refunds, we can instead include an amount object in the JSON payload.
curl -v https://api.sandbox.paypal.com/v1/payments /sale/CARMAXYZC6136044L/refund \ -H "Content-Type:application/json" \ -H "Authorization: Bearer Access-Token" \ -d '{}'
Note: We should substitute all call-specific parameters, such as tokens and IDs, with our own. Response state of the refund:
pending- The refund is pending. completed- The refund has successfully completed. failed- The refund failed.
Refund a captured payment; We can also refund a captured payment: API:
https://api.paypal.com/v1/payments/capture/{capture_id}/refund
Note: We must provide an amount object for both full and partial refunds.
curl -v https://api.sandbox.paypal.com/v1/payments/capture/CARMAXYZC6136044L/refund \ -H "Content-Type:application/json" \ -H "Authorization: Bearer Access-Token" \ -d '{ "amount": { "currency": "USD", "total": "50.54" }, "description": "This is the capture refund description." }' Reference: https://developer.paypal.com
Method 2:
Paypal refund by using Active Merchant Gem:
ActiveMerchant Integration: http://railscasts.com/episodes/145-integrating-active-merchant
In our Application;
config/environment/development.rb
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test ::GATEWAY = ActiveMerchant::Billing::PaypalGateway.new( :login => "seller_1229899173_biz_api1.xyz.com", :password => "FXWU58S7KXFC6HBE", :signature => “AGjv6SW.mTiKxtkm6L9DcSUCUgePAUDQ3L- kTdszkPG8mRfjaRZDYtSu"
)
end
Refunds a transaction: Take a look into paypal_common_api.rb file in Active Merchant Gem;
https://github.com/activemerchant/active_merchant/blob/master/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb
-
For a full refund pass nil for the amount:
gateway.refund nil, 'CARMAXYZC6136044L'
This will automatically make the :refund_type be “Full”.
-
For a partial refund just pass the amount as usual:
gateway.refund 100, 'CARMAXYZC6136044L' def refund(money, identification, options = {}) commit 'RefundTransaction', build_refund_request(money, identification, options) end
Ex:
Gateway.refund(nil,'CARMAXYZC6136044L') => Full Refund. Gateway.refund(798,'CARMAXYZC6136044L') => Partial Refund.
Reference: http://www.rubydoc.info/github/Shopify/active_merchant/ActiveMerchant/Billing/PaypalCommonAPI
Method3: Read More From Here==> http://www.railscarma.com/blog/technical-articles/ways-handling-paypal-refunds-rails/
How to generate & add sitemap to your Rails Application
Generate Sitemap: Required Gem: Sitemap generator:- github.com/kjvarga/sitemap_generator
SitemapGenerator is the easiest way to generate Sitemaps in Ruby. Rails integration provides access to the Rails route helpers within our sitemap config file and automatically makes the rake tasks available to us. Or if we prefer to use another framework, we can! We can use the rake tasks provided or run our sitemap configs as plain ruby scripts.
Sitemaps XML format:
The Sitemap protocol format consists of XML tags. All data values in a Sitemap must be entity-escaped. The file itself must be UTF-8 encoded.
The Sitemap must: Begin with an opening <urlset> tag and end with a closing </urlset> tag. Specify the namespace (protocol standard) within the <urlset> tag. Include a <url> entry for each URL, as a parent XML tag. Include a <loc> child entry for each <url> parent tag.
All other tags are optional. Also, all URLs in a Sitemap must be from a single host, such as www.xyz.com or estore.xyz.com. For more details: http://www.sitemaps.org/protocol.html
How to add a sitemap to a Rails app:
1, View for your sitemap:
# app/views/mysitemap/index.xml.erb
2, At your Controller: Let it be our object in view is @articles variable. It needs to get that from a mysitemap controller:
# app/controllers /mysitemap_controller.rb MysitemapController < ApplicationController layout nil def index headers['Content-Type'] = 'application/xml' respond_to do |format| format.xml {@articles = Article.all} end end end
3, Add a route:
# config/routes.rb get 'sitemap.xml', :to => 'sitemap#index', :defaults => {:format => 'xml'}
How to convert XML file to HTML: Read From Here http://goo.gl/Vp3chb
How To Generate a Swagger Docs For Rails API
Making API for a Rails application is simple for a Ruby on Rails developer. In any case, how different clients/customers will know whether the API is working fine or not without a customer side application. Is there any answer for this which I can report for API inside the Rails application, The answer is yes we have numerous instruments and methodologies however I would favor swagger UI.
In this article I am going to disclose how to make Rails API documentation using swagger UI.
Prerequisites:- I am going to use one sample posts application which serves API calls.
Gem:- To Integrate swagger UI for Rails API I am using a gem called swagger-docs. Add this gem to your Gemfile in your application and do bundle install.
Swagger initializer file:- After bundling the gem create an initializer in config/initializers(e.g. swagger.rb) and specify the following options:
#File config/initializers/swagger.rb Swagger::Docs::Config.register_apis({ "1.0" => { # the extension used for the API :api_extension_type => :json, # the output location where your .json files are written to :api_file_path => "public/apidocs", # the URL base path to your API :base_path => "http://localhost:3000", # if you want to delete all .json files at each generation :clean_directory => true, # add custom attributes to api-docs :attributes => { :info => { "title" => "Your application title", "description" => "Rails API documention with Swagger UI.", "termsOfServiceUrl" => "", "contact" => "" } } } })
Refer below url for the list of configarations
https://github.com/richhollis/swagger-docs#configuration-options
swagger_controller and swagger_API are helpers to provide swagger UI documentation.
module Api module V1 class PostsController < ApplicationController respond_to :json swagger_controller :posts, 'Post Controller' swagger_api :create do summary 'Creating posts' notes 'Should be used for creating posts' param :form, 'post[name]', :string, :required, 'name' param :form, 'post[publish]', :boolean, :required, 'publish' end swagger_api :index do summary 'Get all the posts' notes 'Should be used for fetching all posts' param :header, :Authoraization, :string, :required, 'Authoraization' response :unauthorized response :ok, "Success" end swagger_api :show do summary 'Get all the posts' notes 'Should be used for fetching a post' param :path, :id, :string, :id response :unauthorized response :ok, "Success" end swagger_api :destroy do summary 'Destroy the post' notes 'Should be used for destroying a post' param :path, :id, :string, :id response :unauthorized response :ok, "Success" end end end end
Read More From Here http://goo.gl/dMVHon
Usage of SQL and NoSQL Databases in single rails application(MySQL, PostgreSQL and MongoDB)
There are distinctive reasons why you should think about having various databases in your Ruby on Rails application. In my situation, I expected to store large quantities of data.
Consider default database is MySQL. In our application database.yml file write connections for MySQL in normal way. After that, for connecting postgresql in the same application we need to create custom files.
Create the custom database files to connect postgresql
We’re going to set up a second database called “Stats”
First of all, create the file config/database_stats.yml and populate it as you do with the primary database’s config file.
Your file will look something like this:
development: adapter: postgresql encoding: utf8 reconnect: false database: db_info_development pool: 5 host: localhost username: postgres password:
We’re now going to create a directory that will hold the schema and all the migrations of the Stats database.
Create directory with name db_stats in the rails root and copy the structure as mentioned below
–db –migrate schema.rb seeds.rb –db_stats –migrate schema.rb seeds.rb
The created files should be empty.
For handling stats database, we need to write custom tasks for creation, migrations and other functionalities.
Create a file lib/tasks/db_stats.rake with the below content
namespace :stats do namespace :db do |ns| task :drop do Rake::Task[“db:drop”].invoke end task :create do Rake::Task[“db:create”].invoke end task :setup do Rake::Task[“db:setup”].invoke end task :migrate do Rake::Task[“db:migrate”].invoke end task :rollback do Rake::Task[“db:rollback”].invoke end task :seed do Rake::Task[“db:seed”].invoke end task :version do Rake::Task[“db:version”].invoke end namespace :schema do task :load do Rake::Task[“db:schema:load”].invoke end task :dump do Rake::Task[“db:schema:dump”].invoke end end namespace :test do task :prepare do Rake::Task[“db:test:prepare”].invoke end end
# append and prepend proper tasks to all the tasks as defined above
ns.tasks.each do |task| task.enhance [“stats:set_custom_config”] do Rake::Task[“stats:revert_to_original_config”].invoke end end end task :set_custom_config do
# save current vars
@original_config = { env_schema: ENV[‘SCHEMA’], config: Rails.application.config.dup }
# set config variables for custom database
ENV[‘SCHEMA’] = “db_stats/schema.rb” Rails.application.config.paths[‘db’] = [“db_stats”] Rails.application.config.paths[‘db/migrate’] = [“db_stats/migrate”] Rails.application.config.paths[‘db/seeds’] = [“db_stats/seeds.rb”] Rails.application.config.paths[‘config/database’] = [“config/database_stats.yml”] end task :revert_to_original_config do # reset config variables to original values ENV[‘SCHEMA’] = @original_config[:env_schema] Rails.application.config = @original_config[:config] end end
Once all of this setup is done, we can create the stats database and run its first migration:
$ rake stats:db:create $ rake stats:db:migrate
This will generate the Stats database schema file in db_stats/schema.rb.
Add a custom migration generator We cannot use rails generator because the path hardcodes the db/migrate. Read more From Here http://goo.gl/jVCVRJ
Search Kick Gem – To Make Your Search Intelligent On Rails App
Search kick Gem is a Ruby gem that runs on top of Elasticsearch and makes it easy to make searches in a Rails-friendly fashion. In addition, it allows you to add more features including analytics, autocomplete, and personalized results. Searchkick realizes what your users are searching for. As more individuals hunt, it gets more brilliant and the outcomes improve. It’s benevolent for designers – and supernatural for your users. It handles stemming, special characters, extra whitespace, misspellings, custom synonyms. To get started, make sure that you have Elasticsearch installed on your home computer. Depending on your operating system, the installation process is slightly different and make sure you have at least Java 7. Once you have that done, add and install searchick to your Rails application by adding the following to your Gemfile and running bundle install.
gem ‘searchkick’
When you have both installed and ready to go, you need to indicate which models you might want to be able to search through in your application. Just add searchkick to the model file to make it work. Then, we need to reindex the models so that Elasticsearch can run properly. In your terminal, run:
rake searchkick:reindex:all
Seeking with searchkick is entirely straightforward. Basically run YourModel.search, trailed by the parameters of the search and any filters that you want to add on. For instance, one of more complex searches is below:
@offers = Offer.search params[:search], page: params[:page], per_page: 10, order: {starttime: :desc}, fields: [{offer_name: :word_start}, { offer_request_name: :word_start}:price], where: { starttime: { gte: DateTime.strptime(params[:fromdate],‘%m/%d%Y’), lte: DateTime.strptime(params[:todate],‘%m/%d/%) } }
In this search, we take the search query of the user with params[:search], and look through of the lessons with the following conditions:
Read More From Here : http://www.railscarma.com/blog/technical-articles/search-kick-gem-to-make-your-search-intelligent-on-rails-app/
How to use Acts_As_Votable Gem
Acts_As_Votable is ruby gem specifically written for Rails/ActiveRecord models and This gem allows any model to be voted on upvote/downvote like/dislike, etc. It allows any model to be voted under arbitrary scopes using this gem we can vote any model. votes do not have to come from a user, they can come from any model (such as a Group or Team) and it provide an easy to write/read syntax.
Gem Installation
gem ‘acts_as_votable’
Add above line in Gemfile and run bundle install
Supported ruby and rails versions
Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.0 Rails 3.0, 3.1, 3.2, 4.0, 4.1+
This Gem uses vote table to save all voting information. To generate vote migration run below commands
rails generate acts_as_votable:migration rake db:migrate
To rate any model just use “acts_as_votable” in model
Example:
class Article < ActiveRecord::Base acts_as_votable end @article = Article.new(:name => ‘my new article’) @article.save @article.liked_by @user @article.votes_for.size # => 1
Read More From Here http://goo.gl/emtP8K
Previewing Emails in Rails Applications With the Mail_View Gem
Sending an email from an application through a development or staging environment can be cumbersome especially when you want to preview the mail before you hit the send button. With the gem ‘mail_view, you can easily preview emails right from your development environment. Previewing mail is important to ensure that you are sending the right email and to the right person.
Never send a mail in dark anymore with the ‘mail_view gem! Check out more below on how it can be implemented in your application during the development stage.
Rails Email Preview helps us to quickly view the email in web browser in development mode.
-
Add “gem ‘rails_email_preview’, ‘~> 0.2.29’ “ to gem file and bundle install.
-
Run “rails g rails_email_preview:install” this creates initializer in config folder and add routes.
-
Run “rails g rails_email_preview:update_previews” this crates mailer_previews folder in app directory.
Generator will add a stub to each of your emails, then u populate the stub with mock data.
Ex:
class UserMailerPreview def invitation UserMailer.invitation mock_user(‘Alice’), mock_user(‘Bob’) end def welcome UserMailer.welcome mock_user end private def mock_user(name = ‘Bill Gates’) fake_id User.new(name: name, email: “user#{rand 100}@test.com”) end def fake_id(obj) obj.define_singleton_method(:id) { 123 + rand(100) } obj end end
-
Parameters in search query will be available as an instance variable to preview class.
Ex: if we have a URL like “/emails/user_mailer_preview-welcome?user_id=1” @user_id is defined in welcome method of UserMailerPreview it helps us to send mail to specific user.
class UserMailerPreview def welcome user = @user_id ? User.find(@user_id) : mock_user UserMailer.welcome(user) end end
-
To access REP url’s like this
rails_email_preview.rep_root_url rails_email_preview.rep_emails_url rails_email_preview.rep_email_url(‘user_mailer-welcome’)
-
We can send emails via REP, this will use environment mailer settings. Uncomment this line in the initializer to disable sending mail in test environment.
config.enable_send_email = false
References :
-
github.com/glebm/rails_email_preview
-
richonrails.com/articles/action-mailer-previews-in-ruby-on-rails-4-1
Read More From Here>>> http://goo.gl/KQBk5S
Scheduling Recurring Events with Ice Cube Gem
Ice_cube is a ruby library for effectively taking care of repeated events (schedules). The force lies in the ability to indicate multiple rules, and have ice_cube rapidly make sense of whether the schedule falls on a specific date (.occurs_on?), or what times it happens at (.occurrences, .first, .all_occurrences).
How to get ice cube
For install use the below syntax
gem install
if you want to get the code
gem clone git://github.com/seejohnrun/ice_cube
For creating icecube schedule
schedule = IceCube::Schedule.new if we want to speciy startdate and enddate we have option to specify in the above mentioned schedule schedule = IceCube::Schedule.new(start = Time.now, :end_time => start + 600)
Daily schedules
After creating schedule we have an option to add recurrence rule for the above mentioned schedule
consider “schedule every day” on above mentioned time
schedule.add_recurrence_rule IceCube::Rule.daily
consider the same schedule with repeat “n” number of days
schedule.add_recurrence_rule IceCube::Rule.daily(repeat_every_n_days)
in place of repeat_every_n_days you have option to specify the number of days For Weekly Monthly & Hourly You can Read It From Here http://goo.gl/XGmXp1
Volt Framework for Ruby
Volt – a new Framework for Ruby where both the server and client sides are written in Ruby via OPAL (a ruby to JavaScript compiler) so developer can write dynamic applications without writing a single JavaScript code. Volt is similar to Meteor but it doesn’t have all the portions of Meteor.
The Basic Setup for Volt Framework
Let us install Volt and create an empty app. Make sure that you have ruby (>2.1.0) and ruby gems installed.
gem install volt
We can create a new project using the volt gem:
volt new sample_project
Fire up the web server:
bundle exec volt server
We can access the Volt console with:
bundle exec volt console
The Opal Compiler
Volt applications run Ruby on both frontend and backend. So the puts statement in a controller action appears in browser window and not in terminal console. And also writing Ruby code for the front end with Volt is very easy. The opal compiler translates Ruby to JavaScript. Amazing thing about it is that there is no compilation process to follow and no build tools to install. When you run volt server, everything takes place in the background. No refresh or restart is needed when you do changes to code and data.
Calling a JavaScript alert with Ruby
# Calling JavaScript functions in Ruby module Main class MainController < Volt::ModelController # Called from front end when “todos” route loads. def todos alert ‘totes amaze’ end end end
Easy Syncing via Reactive Models
Concentrate more on this part when learning volt. Volt::Model acts as hash-like Ruby objects that sync between the front end and back end simultaneously. Usually, updates to the model happens automatically. The concept of “stores” in Volt is used to sync application data in persistent and non-persistent forms. And also a uniform means of syncing data between local storage, MangoDB, cookies, sessions and URL params.
Let’s check how to create real-time chat app of Ruby and HTML:
# Create a persistent data model. This gets stored in MongoDB. class ChatMessage < Volt::Model end
View Code:
<:Body> <form e-submit=”say”> <input class=”form-control” type=”text” value=”{{ page._input }}” /> </form> <ul> {{ _chat_messages.each do |msg| }} <ul> <button e-click=”msg.destroy”>X</button> {{ msg._text }} </ul> {{ end }} </ul>
Full HTTP Endpoint Support
Volt is not only for real-time framework. It also provides workflows for traditional HTTP application development. Checkout an example from GitHub :
# Routes for HTTP endpoint get ‘/simple_http’, controller: ‘simple_http’, action: ‘index’ get ‘/simple_http/store’, controller: ‘simple_http’, action: ‘show’ post ‘/simple_http/upload’, controller: ‘simple_http’, action: ‘upload’ # Example controller class SimpleHttpController < Volt::HttpController def index render text: ‘this is just some text’ end def show render text: “You had me at “\ “#{store._simple_http_tests.first._name}” end def upload uploaded = params[:file][:tempfile] File.open(‘tmp/uploaded_file’, ‘wb’) do |f| f.write(uploaded.read) end render text: ‘Thanks for uploading’ end end
How to Add Functionality to Ruby Classes with Decorators
Decorators allow us to add behavior to objects in runtime and don’t affect other objects of the class. Decorators can be applied when you need to dynamically add and remove responsibility to a class. The decorator pattern is a helpful alternative to creating sub-classes. They give additional functionality to a class while still keeping the public API consistent. Let’s look at an example to understand the importance of Ruby Decorators.
consider we have a Tattoo class with a price method that returns 300.
Class Tattoo def price 300 end end
Now we will add an extra color as a feature, and the price would be increased by 150
The simplest way is to create a TattooWithColour subclass that returns 450 in the price method.
class TattooWithColour < Tattoo def price 450 end end
Next, we need to represent a big tattoo that adds 200 to the price of our tattoos. We can represent this using a BigTattoo subclass of Tattoo.
class BigTattoo < Tattoo def price 500 end end
We could also have bigger sized tattoos and they may add further price to our BigTattoo. If we were to consider that these tattoos types could be used with colours, we would need to add BigTattooWithColour and BiggerTattooWithColour subclasses.
With this method, we end up with total of 6 classes. Even Double that the number if you want to represent these combinations with extra designs on tattoo. Inheriting dynamically with modules
To simplify our code, we may use modules to dynamically add behavior to our Tattoo class. Let’s write ColourTattoo and BigTattoo modules for this.
module ColourTattoo def price super + 150 end end module BigTattoo def price super + 200 end end
Now we can extend our tattoo objects dynamically using the Object#extend method.
tattoo = Tattoo.new tattoo.extend(ColourTattoo) tattoo.extend(BigTattoo)
This is good improvement over our inheritance based implementation. Instead of having sub classes, we just have one class and 3 modules. If we needed to add extra design to the equation, we need just four modules instead of 12 classes. Applying the decorator pattern
This module based solution has simplified our code greatly, but we can still improve it by using the decorator. We will consider a BiggerTatto as being formed by twice adding 150 to the cost of a Tattoo.
We can’t do this by our module based approach. It would be tempting to call tattoo.extend(BigTattoo) twice to get BiggerTattoo. Extending module second time has no effect when we have already used extend ones.
If we were to continue using the same implementation, we would need to have a BiggerTattoo module that returns super + 300 as the cost. Instead, we can use decorator that can be composed to build complex objects. We start with a decorator called BigTattoo that is a wrapper around a Tattoo object.
class BigTatto def initialize(tattoo) @tattoo = tattoo end def price @tattoo.price + 150 end end
Bigger Tattoo can now be created by using this wrapper twice on a Tattoo object.
tattoo = Tattoo.new big_tattoo= BigTattoo.new(tattoo) bigger_tattoo = BigTattoo.new(big_tattoo)
We can similarly represent colour tattoo using a TattooWithColour decorator. Using just three classes, we are now able to represent 6 types of tattoo.
Read More From Here http://www.railscarma.com/blog/technical-articles/step-step-guide-building-first-ruby-gem/
Step-By-Step Guide to Building Your First Ruby Gem
Nowadays all the functionalities in Rails are built as Ruby gems. For example we can use devise gem for the authentication part of the application. It’s like a package or library that is written in Ruby programming language. Moreover it can be imported and used by others in their programs.
Step 1 Bundler is like a dependency management tool for Ruby, which is also used by Rails. We will use Bundler for the basic gem structure. It helps us to install the correct versions of the gem and forces us to use the same in the application. So the command for that is, gem bundler install After bundling, we should specify the gem “name” that we are going to create i.e. Bundle gem “testgem” will create a repository shown below
So in this we can see the basic gem structure. Under the lib folder, version file will be used to mention the version of the Gem. We can edit the version as per our convenience and release it that will be the version in Rubygems.
Step 2 We will consider testgem.gemspec, with testgem as the name of the gem that we will create for sample. It will be used to set up the gem on rubgems, for e.g., name of the gem, summary, description, files that are required in this project, test files that are used to testing the files in the project etc.
Rake file: – This makes releasing the new versions of the gem, and also helps other developers to check the test cases if they are going to modify the particular gem. After the rake, we should create a test folder and test cases for each segments will be included here in the app directory.
Step 3 Planning to make a rubygem, then we need to analyse the requirements what to build up and what all functionalities should be included in that. While generating, we should create a sample.rb file inside lib folder and create own class with namespace because the other plugin has also the same classes then it will get conflict in the names. And require the sample.rb file in the testgem.rb file like reqiure “testgem/sample”.
Step 4 We have require “bundler/gem_tasks” in rake file so when we run rake release, it will release the gem to ruby gems and make it available. Push to git repository
SOCKET LIBRARY IN RUBY ON RAILS
There are basically two levels of accessing network services in case of rails .
The socket and network libraries are such important parts of integrating Ruby applications with the Internet and other communications-based environments.
One is through socket libraries provide low level access to connection oriented and connection-less protocols. Where user can implement client and server connection. Ruby is also having Network libraries that provide users a high level access to specific network protocols like FTP,HTTP and Etc.
At a low level, you can access the basic socket support in the underlying operating system, which allows you to implement clients and servers for both connection-oriented and connectionless protocols. Ruby also has libraries that provide higher-level access to specific application-level network protocols, such as FTP, HTTP, and so on.
What are Sockets?
Sockets are basically a bidirectional communications channel. Sockets may communicate within a process, between processes on the same machine, or between processes on different continents. Sockets can be implemented on different channels : Unix domain sockets, TCP, UDP, and so on. The socket library mainly provides specific classes and interface for handling a transports.
A SimpleClient:
Hereis a very basic client program which will open up a connection to a given port and given host. Ruby class TCPSocket provides open function to open a socket. The TCPSocket.open(hosname, port ) opens a TCP connection to hostname & theport.
Once socket is open, you can actually read that particular thing like IO object. When it’s done, just remember to close it, as you close that file. The following code connects to a given host and port, reads any available data from the socket, and then exits:
require ‘socket’ # Socket in standard library
hostname = ‘localhost’
port = 8080
s = TCPSocket.open(hostname, port)
while line = s.gets # Gets and Read the lines from the socket
puts line.chop # And print with platform line terminator end
s.close # socket Closed
A Simple Server: To write Internet servers, we basically use this TCPServer class. A TCPServer object is a factory for TCPSocket objects. Now call TCPServer.open(hostname, port function to specify a port for your service and create a TCPServer object. Next, call the accept method of the returned TCPServer object. This particular method waits till client connects to the port you specified above, and then returns a TCPSocket object that basically represents the connection to that client.
require ‘socket’ # Get sockets from stdlib server = TCPServer.open(8080) # Socket to listen on port 8080 loop { # Servers run forever
client = server.accept # Wait for a client to connect client.puts(Time.now.ctime) # Send the time to the client client.puts "Closing the connection. Bye!" client.close # Disconnect from the client
}
Now run this server in background and then run above client to see the result.