It just happened I had profile SQL query in my hanami application. And I want to save this knowledge that’s why I created this post.
If you are using ROM, this post will be helpful for you too, because hanami-module uses ROM. So, in hanami, you have a simple ability for profiling your SQL queries.
For that, you need to use some methods for Sequel::Dataset instance.
Fox example, if you want to get pure sql sting you can use #sql method:
>> puts UserRepository.new.users.where(admin: true).dataset.sql
SELECT * FROM "users" WHERE ("admin" IS TRUE) ORDER BY "users"."id"
=> nil
or if you need to call ANALYZE or EXPLAIN psql methods you can use similar methods:
>> puts UserRepository.new.users.where(admin: true).dataset.analyze
Sort (cost=19.38..19.79 rows=165 width=213) (actual time=0.019..0.019 rows=1 loops=1)
Sort Key: id
Sort Method: quicksort Memory: 25kB
-> Seq Scan on users (cost=0.00..13.30 rows=165 width=213) (actual time=0.013..0.014 rows=1 loops=1)
Filter: (admin IS TRUE)
Rows Removed by Filter: 1
Planning time: 4.362 ms
Execution time: 0.039 ms
=> nil
>> puts UserRepository.new.users.where(admin: true).dataset.explain
Sort (cost=19.38..19.79 rows=165 width=213)
Sort Key: id
-> Seq Scan on users (cost=0.00..13.30 rows=165 width=213)
Filter: (admin IS TRUE)
=> nil
It’s a second part of my post series about ruby tips. Today you’ll learn more about:
Special values
Symbol
Array
Hash
Range
CAUTION: These tips are not equally feat to production. Lots of them are just interesting solutions which you’ll not find anywhere else. Use them at your own risk.
In ruby you can find security levels for your code.
The Ruby security level is represented by the $SAFE global variable.
The value ranges from minimum value 0 to maximum value 4.
$SAFE
Constraints
0
No checking of the use of externally supplied (tainted) data is performed. This is Ruby’s default mode.
>= 1
Ruby disallows the use of tainted data by potentially dangerous operations.
>= 2
Ruby prohibits the loading of program files from globally writable locations.
>= 3
All newly created objects are considered tainted.
>= 4
Ruby effectively partitions the running program in two. Nontainted objects may not be modified. Typically, this will be used to create a sandbox: the program sets up an environment using a lower$SAFE level, then resets $SAFE to 4 to prevent subsequent changes to that environment.
Email Regexp
In ruby you can find regexp for emails. If you want to use it, you have to require uri
library and call URI::MailTo::EMAIL_REGEXP constant.
DATA object
The global DATA variable in ruby allows us to access the text at the end of our file
listed after the __END__ block. This can be surprisingly useful, for instance if we
need to extract information from a rather large data blob.
# in one filerequire"json"putsJSON.load(DATA)# this DATA required text bellow __END____END__
{
"records": [
{
"artist":"Iggy Pop",
"title":"Lust for Life"
},
{
"artist":"Television",
"title":"Marquee Moon"
},
{
"artist":"Talking Heads",
"title":"Talking Heads: 77"
}
]
}
str="Help! All parentheses have been flipped )and I am sad(!"str.gsub(/[\(\)]/,{"("=>")",")"=>"("})# => "Help! All parentheses have been flipped (and I am sad)!"
I’ve been collecting the ruby tips for a long time. And now I’m ready to share them all. Hope you’ll find some interesting solutions, tips and sugars for ruby.
And today we’re talking about:
Kernel
Class
Object
Proc (lambda)
Method
CAUTION: These tips are not equally feat to production. Lots of them are just interesting solutions which you’ll not find anywhere else. Use them at your own risk.
Kernel
Char
If you want to get string with only one char you can use ?* syntax.
Also you can use this hack in various methods like ‘join’
Ruby went out and got itself an identity method.
For those not familiar, an identity method returns the object it’s called on:
1.itself# => 1
j and jj
When you require json library you get two interesting methods.
First is Kernel#j.
This method outputs object to STDOUT as JSON strings in the shortest form, that is in one line.
require'json'h={a: 1,b: 2}j(h)
And second is Kernel#jj
This method outputs object to STDOUT as JSON strings in a pretty format, with indentation, and over many lines.
Allocates space for a new object of class’s class and does not call initialize on the new instance.
The returned object must be an instance of a class.
Refinements are designed to reduce the impact of monkey patching on other users of the monkey-patched class.
Refinements provide a way to extend a class locally.
Ruby defines curry for Method and Proc, allowing procs to return partially applied procs when they get called with fewer than the required number of arguments.
Note: While Proc#curry has been around since Ruby 1.9, Method#curry was only added in Ruby 2.2.0. For versions before 2.2.0, you will first need to convert your method object to a proc via Method#to_proc.
I have a problem. Each time I want add domain to my custom github project
I forget what I should do exactly. That’s why I want to post this SO answer in my blog.
I hope it would helpful not only for me.
To Setup a custom domain for your gh-pages project repo that handles
www.yourdomain.com and yourdomain.com (assumes you already have a gh-pages
branch on your repo) you need this:
From your project repo, gh-pages branch. Create a CNAME file with the contents yourdomain.com.
In your DNS manager, setup two CNAME records. One for the root apex (@) and one for www. Both point to YOURusername.github.io. If your DNS provider does NOT support ALIAS records on the root apex (@), simply create A records that point to 192.30.252.153 and 192.30.252.154.
Sometimes you need to preview your emails in development enviroment.
For this you can use use letter_opener gem.
Because hanami uses mail gem, letter_opener integration will be easy.
Firstly you need add gem to your Gemfile:
gem"letter_opener",group: :development
Secondly you need add new delivery method to your lib/repository_name.rb file:
Sometimes you need to build API serveice in your rails application.
Of course you can use popular solutions as grape or rails-api gems.
And also you can find real examples in gitlab or rubygems projects.
But today I’m going to tell you about other framework. It’s roda.
Roda was created by Jeremy Evans and it’s fast and simple ruby routing framework.
So why should you take a look on it?
There’s a list of advantages of this framework:
Fast;
Simple;
Roda provides simple way to working with big count of different plugins;
You can use any architecture with it;
So I mentioned that roda is fast. If you want to verify this, just check this benchmark repository and you’ll see that roda is really fast.
For example, I run benchmarks on locally and get this result:
Framework Requests/sec % from best
----------------------------------------------
mustermann 9389.60 100.0%
roda 9252.03 98.53%
rack 9246.16 98.47%
hanami-router 6240.81 66.47%
sinatra 2935.63 31.26%
grape 2512.17 26.75%
Integration
Roda based on rack. That’s why this integration with rails will be very simple.
Firstly you need to add roda gem to your gemfile:
gem'roda'
Secondly you need to create simple roda application.
Note that you need to use json and all_verbs plugins.
The first one needs to JSON responce and the second one provides all REST methods for your application (like put, patch, etc).
I puted my roda application in to lib/api/base.rb path but you can use whatever you waht.
And the last part, we need to split our application to different modules with different logic and routes.
For this we have to create required module. In an example I created Users module with all REST routes:
That’s all. Now we have a simple roda API application which integrated to our rails app.
Problems / future
In the last part I want to list problems and ideas what I want to solve in future.
Roda doesn’t have a swagger integrating from the box. Now I’m thinking about using swagger-block gem for it.
Also roda doesn’t typecast your params. I know that grape uses virtus gem for this. And this feature you should realize by youself too.
Conclusion
On this blog post I wanted to show you that you’re not limited only to popular API server gems.
As you can see roda have amazing ideas and properties such as modulatiry, simplicity, speed and stability.
Also this framework has a simple way to integration in to your rails application.
If you need the simplest and easiest way to adding authentication logic in your hanami app (to admin app for example) you always can use Rack::Auth::Basic class.
For this you need to add following lines of code to your controller.prepare configuration block:
# apps/admin/application.rbcontroller.preparedo# ...# some codeuseRack::Auth::Basic,'Message'do|username,password|username=='admin'&&password=='password'endend
Happy authenticating!
P.S.: also if you need something more complicated you can reed this thread on hanami forum.
Today I read a nice blog post by Kir Shatrov about Profiling RSpec examples with Stackprof
and I wondered if I could repeat this trick with minitest? This question is very important for me
because I ofen use minitest for my job and OSS projects. Also a lot of cool projects use minitest
(for example, sidekiq, rails, lotus, etc).
In reality, to do that in minitest as easy as in RSpec, and the only difference is that you need
to install a separate gem.
If you want to render some result of ruby block in your layout file, you may run into some problems.
For example, your result may be repeated on page or you can get something worse.
Of cource you can use captire method from rails and sinatra-contrib librares.
But what will you do if you can’t use these methods or you need something easier?
I faced a similar problem (for example, in sidekiq) and I used own capture method for layout files.