infinum / rails-handbook Goto Github PK
View Code? Open in Web Editor NEWDescribing the development process used by the Infinum Rails Team.
Describing the development process used by the Infinum Rails Team.
Greetings Infinum peeps ๐
I stumbled upon your guide last night and enjoyed it a lot!
It was refreshing to read through how you structure your projects and your approach to them.
I came across a typo in the Authentication document:
They usually livie longer than access tokens
-> They usually live longer than access tokens
.
Thank you for the awesome guide ๐
Might just be a good place to put all good articles about testing and best practices.
For example:
https://medium.com/just-tech/rspec-controller-or-request-specs-d93ef563ef11
https://docs.gitlab.com/ee/development/testing_guide/
https://github.com/infinum/rails-handbook/blob/master/Fiscalization.md
Da ostavimo upute za fiskalizaciju javno ili ne?
The ending of the subchapter for page-based pagination should be double checked:
The clause requires scanning all rows included by the offset value, which is inefficient for large offsets and causes performance to suffer the more pages you have (e.g. page 100 is slower to fetch than page 1).
@jerko-culina left a comment stating that the sentence might not be completely true, so let's discuss how we can improve it.
I was using geocoder on a project and my goal was to fetch a particular type of users that were close to a job (user
and job
are names of my AR models). I needed only the first 50 users, so this was the implementation:
geocoder version
MAX_USER_DISTANCE = 200
MAX_SET_OF_USERS = 50
def call
User.near(job_location, MAX_USER_DISTANCE)
.with_user_type_assignee
.limit(MAX_SET_OF_USERS)
end
def job_location
[job.latitude, job.longitude].compact
end
Running this the following sql is produced:
SELECT users.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((20.0 - users.last_latitude) * PI() / 180 / 2), 2) + COS(20.0 * PI() / 180) * COS(users.last_latitude * PI() / 180) * POWER(SIN((-15.0 - users.last_longitude) * PI() / 180 / 2), 2))) AS distance, MOD(CAST((ATAN2( ((users.last_longitude - -15.0) / 57.2957795), ((users.last_latitude - 20.0) / 57.2957795)) * 57.2957795) + 360 AS decimal), 360) AS bearing FROM \"users\" WHERE (users.last_latitude BETWEEN 17.10536433778304 AND 22.89463566221696 AND users.last_longitude BETWEEN -18.08040693114738 AND -11.91959306885262 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((20.0 - users.last_latitude) * PI() / 180 / 2), 2) + COS(20.0 * PI() / 180) * COS(users.last_latitude * PI() / 180) * POWER(SIN((-15.0 - users.last_longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 200) AND \"users\".\"user_type\" = 'assignee' ORDER BY distance ASC LIMIT 50
However, the following error occurred:
ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column "distance" does not exist
LINE 1: ....0 AND 200) AND "users"."user_type" = $1 ORDER BY distance A...
^
: SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM "users" WHERE (users.last_latitude BETWEEN 17.10536433778304 AND 22.89463566221696 AND users.last_longitude BETWEEN -18.08040693114738 AND -11.91959306885262 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((20.0 - users.last_latitude) * PI() / 180 / 2), 2) + COS(20.0 * PI() / 180) * COS(users.last_latitude * PI() / 180) * POWER(SIN((-15.0 - users.last_longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 200) AND "users"."user_type" = $1 ORDER BY distance ASC LIMIT $2) subquery_for_count
from /Users/cilim/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activerecord-5.1.3/lib/active_record/connection_adapters/postgresql_adapter.rb:614:in `async_exec'
I had to fallback to using Rubies take(50)
method on the produced AR relation ( without the limit
everything was ok).
I decided to refactor the code and substitute geocoder with geokit-rails.
geokit-rails version
MAX_USER_DISTANCE = 200
MAX_SET_OF_USERS = 50
def call
User.within(MAX_USER_DISTANCE, origin: job)
.with_user_type_assignee
.limit(MAX_SET_OF_USERS)
end
And it works like a charm!
SQL query:
"SELECT \"users\".* FROM \"users\" WHERE (users.last_latitude IS NOT NULL AND users.last_longitude IS NOT NULL) AND (users.last_latitude>17.10860294292818 AND users.last_latitude<22.89139705707182 AND users.last_longitude>-18.07661470455701 AND users.last_longitude<-11.923385295442989) AND ((\n" +
" (ACOS(least(1,COS(0.3490658503988659)*COS(-0.2617993877991494)*COS(RADIANS(users.last_latitude))*COS(RADIANS(users.last_longitude))+\n" +
" COS(0.3490658503988659)*SIN(-0.2617993877991494)*COS(RADIANS(users.last_latitude))*SIN(RADIANS(users.last_longitude))+\n" +
" SIN(0.3490658503988659)*SIN(RADIANS(users.last_latitude))))*3963.1899999999996)\n" +
" <= 200)) AND \"users\".\"user_type\" = 'assignee' LIMIT 50"
and no errors ๐
Geocoder | Geokit-Rails | |
---|---|---|
Stars | 4802 | 1286 |
Issues | 38 | 58 |
Open pull requests | 19 | 1 |
Closed pull requests | 512 | 39 |
First commit | 15.4.2009. | 18.12.2008. |
Last commit | 17.11.2017. | 9.8.2017. |
Popularity | 9.4 and growing | 7.2 stable |
Activity | 7.5 stable | 3.9 |
Geocoder | Geokit-Rails | |
---|---|---|
Postgis solution | Yes | No |
Geocoding by street * | Yes | Yes |
Geocoding by IP address* | Yes | Yes |
Reverse geocoding* | Yes | Yes |
Distance queries | Yes | Yes |
Geocoder | Geokit-Rails | |
---|---|---|
MySQL | Yes | Yes |
Postgresql | Yes | Yes |
SQLite | Yes | No |
MongoDB | Yes | No |
Despite geocoder having a bigger community and looking like it's better from all the above data, I had much less trouble with using geokit-rails on my projects than geocoder.
Also, worth mentioning, substituting the 2 gems was easy and I'm more satisfied with the current code state and the syntax for hooking geocoding features into my models and performing simple/complex queries.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.