Notes posted to Ruby on Rails
RSS feedWays 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/
An example, with expiration time set
e.g.:
Rails.cache.fetch("out_of_stock_products", :expires_in => 5.minutes) do Product.all.joins(:inventory).conditions.where("inventory.quantity = 0") end
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/
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
Integrate enum with PostgreSQL Enumerated Types
Extract from:
http://www.sitepoint.com/enumerated-types-with-activerecord-and-postgresql/
There are 2 things that we need to do before we can use ActiveRecord::Enum with PostgreSQL Enumerated Types: database migration and enum declaration.
First, let’s create the database migration:
$ bundle exec rails generate migration AddGenderToUsers gender:gender
Next, edit the generated migration to add the type:
# db/migrate/20150619131527_add_gender_to_users.rb class AddGenderToUsers < ActiveRecord::Migration def up execute <<-SQL CREATE TYPE gender AS ENUM ('male', 'female', 'not_sure', 'prefer_not_to_disclose'); SQL add_column :users, :gender, :gender, index: true end def down remove_column :users, :gender execute <<-SQL DROP TYPE gender; SQL end end
Once you’re finished with that, run the migration:
$ bundle exec rake db:migrate
Now, we have completed the database migration. The next step is to declare an enum in the User model. Earlier, we used both the Array and Hash forms to declare an enum. For the integration to work, we need to declare an enum using the Hash form:
# app/models/user.rb class User < ActiveRecord::Base enum gender: { male: 'male', female: 'female', not_sure: 'not_sure', prefer_not_to_disclose: 'prefer_not_to_disclose' } end
Finally, we can store ActiveRecord::Enum values using PostgreSQL Enumerated Types. As a bonus, all helper methods provided by ActiveRecord::Enum still work as expected.
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.
foreign_key option
It is also possible to specify that add_foreign_key should be added to the schema:
add_reference(:products, :supplier, foreign_key: true)
Active Record Import
With activerecord-import, you’d just add your records to an array and call import:
records_to_import = pricing_data.map do |location, price| Inventory.new(location: location, price: price) end Inventory.import records_to_import
Location of this method in older versions
Before v3.2.1, this method was in ActiveRecord::Base.create .
Where this method moved to
After v3.1.0, this method moved to ActiveRecord::Persistence::ClassMethods#create .
Careful with arel column
I use what @equivalent suggests a lot but be careful, you MUST state the direction otherwise methods like take/last/first will fail silently!
StatusChange.arel_table[‘created_at’]. asc
not:
StatusChange.arel_table[‘created_at’]
`value` or `text` method with parameter.
If your value or text method requires a parameter, like to_s(:select) then you need to create a separate method that references that in your model, like:
def to_s_select to_s(:select) end
You can’t pass it in as a string like 'to_s(:select)'.
You have to use :to_s_select or 'to_s_select'.
RE: RE: FALSE: Creates record by given attributes only if table is empty
keredson is still a little off on the behavior.
>> Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
This isn’t right, as if you look at the source it calls: “first || create(attributes, &block)”
So in the example of:
User.first_or_create(email: 'derek@somwhere.com')
it would find the first user with any email, and return it. And thats it. The attributes passed in as params are only used in the event that first returns no matches, and create is called.
I’m using it in a way similar to:
Foo.where(bar: baz_params[:bar]).first_or_create(baz_params)
This will find the first Foo where bar is equal to the bar sent from baz_params. If none is found, it will create it. It’s useful for me when importing large amounts of data where I know there will be duplicate records.
Should include information about optional block
If a block exists, will return true if any records in the relation is true for the given block. Otherwise, returns true is there are any records.
Description
Selects the first record within a relation if it exists, otherwise creates a new record with the optional attributes.
No grammatical error
rajivekjain:
“A, B, and C” is correct in English, and is preferred by most style manuals. “A, B and C” is also correct in English. See en.wikipedia.org/wiki/Serial_comma
Default values
By default :on_update and :on_delete have :restrict value.
RE: FALSE: Creates record by given attributes only if table is empty
Dino’s comment was almost certainly due to a misunderstanding of the API, a mistake I made myself the first time I used it, and one I’ve witnessed multiple others make as well.
The fact that this method takes an attributes parameter leads one to think the passed params are the criteria for the selection. At first glance it would appear it would be used like this:
User.first_or_create(email: 'derek@somwhere.com')
Where in reality this would grab the “first” record (say w/ email “john@smith.com”), and change its email to “derek@somwhere.com”, a fairly surprising action that doesn’t obviously fail, leading to some pretty subtle bugs.
In reality it should be used like this:
User.where(email: 'derek@somwhere.com').first_or_create
And the attributes param. isn’t used in 99% of use cases. (If at all - the provision for the block that executes only on create fully duplicates what the attributes parameter can do in a much more obvious way.)
IMHO this is simply a bad API that one just needs to be aware of. But it’s unfair to knock dino for what’s likely a highly common misreading.
FALSE: Creates record by given attributes only if table is empty
I very much doubt that dino’s comment was ever correct, but it certainly isn’t correct now. The behavior liantics describes is correct.
link broken
http://apidock.com/rails/ActionDispatch/Request/body <- request body link
Text values for enum
There is way to have text values for enum. It is useful to have localized select options and latin values in database. 1) User model: enum kind: { ‘текст’=>‘text’, ‘изображение’=>‘picture’, ‘звук’=>‘audio’, ‘видео’=>‘video’ } 2) Edit view: <%= select_tag ‘user[kind]’, options_for_select(User.kinds, @user.kind) %>