It's good to be awesome
Nikola Todorovic
  • Home
  • Hire Me
  • Nikola's Blog
  • Professional Career
  • Biography
  • Photo Gallery
  • Contact

RUBY METAPROGRAMMING

8/12/2015

1 Comment

 
(Note: this post I originally published at the TopTal Blog)
You often hear that metaprogramming is something that only Ruby ninjas use, and that it simply isn't for common mortals. But the truth is that metaprogramming isn't something scary at all. This blog post will serve to challenge this type of thinking and to get metaprogramming closer to the average Ruby developer so that they can also reap its benefits.
Picture
It should be noted that metaprogramming could mean a lot and it can often be very misused and go to the extreme when it comes to usage so I will try to throw in some real world examples that everyone could use in everyday programming.

METAPROGRAMMING

Metaprogramming is a technique by which you can write code that writes code by itself dynamically at runtime. This means you can define methods and classes during runtime. Crazy, right? In a nutshell, using metaprogramming you can reopen and modify classes, catch methods that don’t exist and create them on the fly, create code that is DRY by avoiding repetitions, and more.

THE BASICS

Before we dive into serious metaprogramming we must explore the basics. And the best way to do that is by example. Let’s start with one and understand Ruby metaprogramming step-by-step. You can probably guess what this code is doing:
class Developer

  def self.backend
    "I am backend developer"
  end
  
  def frontend
    "I am frontend developer"
  end

end
We have defined a class with two methods. The first method in this class is a class method and the second one is an instance method. This is basic stuff in Ruby, but there is much more happening behind this code which we need to understand before we proceed further. It is worth pointing out that the class Developer itself is actually an object. In Ruby everything is an object, including classes. Since Developer is an instance, it is an instance of class Class. Here is how the Ruby object model looks like:
Picture
p Developer.class # Class
p Class.superclass # Module
p Module.superclass # Object
p Object.superclass # BasicObject
One important thing to understand here is the meaning of self. The frontend method is a regular method that is available on instances of class Developer, but why is backend method a class method? Every piece of code executed in Ruby is executed against a particular self. When the Ruby interpreter executes any code it always keeps track of the value self for any given line. self is always referring to some object but that object can change based on the code executed. For example, inside a class definition, the self refers to the class itself which is an instance of class Class.
class Developer
  p self 
end
# Developer
Inside instance methods, self refers to an instance of the class.
class Developer
  def frontend
    self
  end
end
 
p Developer.new.frontend
# #<Developer:0x2c8a148>
Inside class methods, self refers to the class itself in a way (which will be discussed in more detail later in this article):
class Developer
  def self.backend
    self
  end
end

p Developer.backend
# Developer
This is fine, but what is a class method after all? Before answering that question we need to mention the existence of something called metaclass, also known as singleton class and eigenclass. Class method frontend that we defined earlier is nothing but an instance method defined in the metaclass for the object Developer! A metaclass is essentially a class that Ruby creates and inserts into the inheritance hierarchy to hold class methods, thus not interfering with instances that are created from the class.

METACLASSES

Every object in Ruby has its own metaclass. It is somehow invisible to a developer, but it is there and you can use it very easily. Since our class Developer is essentially an object, it has its own metaclass. As an example let’s create an object of a class String and manipulate its metaclass:
example = "I'm a string object"

def example.something
  self.upcase
end

p example.something
# I'M A STRING OBJECT
What we did here is we added a singleton method something to an object. The difference between class methods and singleton methods is that class methods are available to all instances of a class object while singleton methods are available only to that single instance. Class methods are widely used while singleton methods not so much, but both types of methods are added to a metaclass of that object.
The previous example could be re-written like this:
example = "I'm a string object"

class << example
  def example.something
    self.upcase
  end
end
The syntax is different but it effectively does the same thing. Now let’s go back to the previous example where we created Developer class and explore some other syntaxes to define a class method:
class Developer
  def self.backend
    "I am backend developer"
  end
end
This is a basic definition that almost everybody uses.
def Developer.backend
  "I am backend developer"
end
This is the same thing, we are defining the backend class method for Developer. We didn’t use self but defining a method like this effectively makes it a class method.
class Developer
  class << self
    def backend
      "I am backend developer"
    end
  end
end
Again, we are defining a class method, but using syntax similar to one we used to define a singleton method for a String object. You may notice that we used self here which refers to a Developer object itself. First we opened Developer class, making self equal to the Developer class. Next, we do class << self, making self equal to Developer’s metaclass. Then we define a method backend on Developer’s metaclass.
class << Developer
  def backend
    "I am backend developer"
  end
end
By defining a block like this, we are setting self to Developer’s metaclass for the duration of the block. As a result, the backend method is added to Developer’s metaclass, rather than the class itself.
Let’s see how this metaclass behaves in the inheritance tree:
Picture
As you saw in previous examples, there’s no real proof that metaclass even exists. But we can use a little hack that can show us the existence of this invisible class:
class Object
  def metaclass_example
    class << self
      self
    end
  end
end
If we define an instance method in Object class (yes, we can reopen any class anytime, that’s yet another beauty of metaprogramming), we will have a self referring to the Object object inside it. We can then use class << self syntax to change the current self to point to the metaclass of the current object. Since the current object is Object class itself this would be the instance’s metaclass. The method returns self which is at this point a metaclass itself. So by calling this instance method on any object we can get a metaclass of that object. Let’s define our Developer class again and start exploring a little:
class Developer

  def frontend
    p "inside instance method, self is: " + self.to_s
  end

  class << self
    def backend
      p "inside class method, self is: " + self.to_s
    end
  end
  
end

developer = Developer.new
developer.frontend
# "inside instance method, self is: #<Developer:0x2ced3b8>"

Developer.backend
# "inside class method, self is: Developer"

p "inside metaclass, self is: " + developer.metaclass_example.to_s
# "inside metaclass, self is: #<Class:#<Developer:0x2ced3b8>>"
And for the crescendo, let’s see the proof that frontend is an instance method of a class and backend is an instance method of a metaclass:
p developer.class.instance_methods false
# [:frontend]

p developer.class.metaclass_example.instance_methods false
# [:backend]
Although, to get the metaclass you don’t need to actually reopen Object and add this hack. You can use singleton_class that Ruby provides. It is the same as metaclass_example we added but with this hack you can actually see how Ruby works under the hood:
p developer.class.singleton_class.instance_methods false
# [:backend]

DEFINING METHODS USING CLASS_EVAL AND INSTANCE_EVAL

There’s one more way to create a class method, and that is by using instance_eval:
class Developer
end

Developer.instance_eval do
  p "instance_eval - self is: " + self.to_s
  def backend
    p "inside a method self is: " + self.to_s
  end
end
# "instance_eval - self is: Developer"

Developer.backend
# "inside a method self is: Developer"
This piece of code Ruby interpreter evaluates in the context of an instance, which is in this case a Developer object. And when you are defining a method on an object you are creating either a class method or a singleton method. In this case it is a class method - to be exact, class methods are singleton methods but singleton methods of a class, while the others are singleton methods of an object.
On the other hand, class_eval evaluates the code in the context of a class instead of an instance. It practically reopens the class. Here is how class_eval can be used to create an instance method:
Developer.class_eval do
  p "class_eval - self is: " + self.to_s
  def frontend
    p "inside a method self is: " + self.to_s
  end
end
# "class_eval - self is: Developer"

p developer = Developer.new
# #<Developer:0x2c5d640>

developer.frontend
# "inside a method self is: #<Developer:0x2c5d640>"
To summarize, when you call class_eval method, you change self to refer to the original class and when you call instance_eval, self changes to refer to original class’ metaclass.

DEFINING MISSING METHODS ON THE FLY

One more piece of metaprogramming puzzle is method_missing. When you call a method on an object, Ruby first goes into the class and browses its instance methods. If it doesn’t find the method there, it continues search up the ancestors chain. If Ruby still doesn’t find the method, it calls another method named method_missing which is an instance method of Kernel that every object inherits. Since we are sure that Ruby is going to call this method eventually for missing methods, we can use this to implement some tricks.
define_method is a method defined in Module class which you can use to create methods dynamically. To use define_method, you call it with the name of the new method and a block where the parameters of the block become the parameters of the new method. What’s the difference between using def to create a method and define_method? There’s not much difference except you can use define_method in combination with method_missing to write DRY code. To be exact, you can use define_method instead of def to manipulate scopes when defining a class, but that’s a whole other story. Let’s take a look at a simple example:
class Developer
  define_method :frontend do |*my_arg|
    my_arg.inject(1, :*)
  end

  class << self
    def create_backend
      singleton_class.send(:define_method, "backend") do
        "Born from the ashes!"
      end
    end
  end
end

developer = Developer.new
p developer.frontend(2, 5, 10)
# => 100

p Developer.backend
# undefined method 'backend' for Developer:Class (NoMethodError)

Developer.create_backend
p Developer.backend
# "Born from the ashes!"
This shows how define_method was used to create an instance method without using a def. However, there’s much more we can do with them. Let’s take a look at this code snippet:
class Developer

  def coding_frontend
    p "writing frontend"
  end

  def coding_backend
    p "writing backend"
  end

end

developer = Developer.new

developer.coding_frontend
# "writing frontend"

developer.coding_backend
# "writing backend"
This code isn't DRY, but using define_method we can make it DRY:
class Developer

  ["frontend", "backend"].each do |method|
    define_method "coding_#{method}" do
      p "writing " + method.to_s
    end
  end

end

developer = Developer.new

developer.coding_frontend
# "writing frontend"

developer.coding_backend
# "writing backend"
That’s much better, but still not perfect. Why? If we want to add a new method coding_debug for example, we need to put this "debug" into the array. But using method_missing we can fix this:
class Developer

  def method_missing method, *args, &block
    return super method, *args, &block unless method.to_s =~ /^coding_\w+/
    self.class.send(:define_method, method) do
      p "writing " + method.to_s.gsub(/^coding_/, '').to_s
    end
    self.send method, *args, &block
  end

end

developer = Developer.new

developer.coding_frontend
developer.coding_backend
developer.coding_debug
This piece of code is a little complicated so let’s break it down. Calling a method that doesn’t exist will fire up method_missing. Here, we want to create a new method only when the method name starts with "coding_". Otherwise we just call super to do the work of reporting a method that is actually missing. And we are simply using define_method to create that new method. That’s it! With this piece of code we can create literally thousands of new methods starting with "coding_", and that fact is what makes our code DRY. Since define_method happens to be private to Module, we need to use send to invoke it.

WRAPPING UP

This is just the tip of the iceberg. To become a Ruby Jedi, this is the starting point. After you master these building blocks of metaprogramming and truly understand its essence, you can proceed to something more complex, for example create your own Domain-specific Language (DSL). DSL is a topic in itself but these basic concepts are a prerequisite to understanding advanced topics. Some of the most used gems in Rails were built in this way and you probably used its DSL without even knowing it, such as RSpec and ActiveRecord.
Hopefully this article can get you one step closer to understanding metaprogramming and maybe even building your own DSL, which you can use to code more efficiently.
1 Comment

RAILS 4 + ANGULARJS + JSON WEB TOKEN AUTHENTICATION

5/8/2015

2 Comments

 
Recently I was contacted by Toptal to join their network as a developer. I heard some good stuff about them before so I decided to give it a go. Toptal is "a network comprised of the most thoroughly screened, talented freelance engineers in the world". To enter the network you have to pass 4 tests. The first one is an interview - a simple English test, the second one is Codility test. The third one is a one-to-one test with a senior developer from the network when you need to solve two problems at limited time. And the last one is to create a full application.
Anyway, I am not going to talk about Toptal, rather than the project they gave me to do as the last part of the screening process. The full text of the project as well as the solution you can find on my GitHub. In this post I will only go through the main things and make some general remarks how development should be done and what you should pay attention, I won't cover every detail because there is too much code. For all the details you have code on GitHub.

Authentication

Since I needed to create API with every operation done using JavaScript I decided to use Angular to create a SPA. And since there is an API and SPA I decided to authenticate users using tokens. I didn't want to use Devise since the basic gem doesn't offer token authentication and then you need to add some other gem to be able to do that so I decided to use so called JWT (JSON web token). More about that technology you can find here.
require 'jwt'

module AuthToken
  def AuthToken.issue_token(payload)
    payload[:exp] = Time.now.to_i + 4 * 3600
    JWT.encode payload, Rails.application.secrets.secret_key_base
  end

  def AuthToken.valid?(token)
    begin
      JWT.decode token, Rails.application.secrets.secret_key_base
    rescue
      false
    end
  end
end
Token generation, encoding and decoding is very simple using existing ruby gem. Only thing you need to do is gather everything in a whole. The general idea when user needs to be authenticated is to generate an API call with the parameters of email and password. If it turns out that this is the valid user, the token is being generated and returned to the user as a JSON response. That response also contains a data what user it is (user_id). The whole token is saved in the browser's local storage. Instead, a token can be stored in a cookie (therefore cookie is used as a storage), more about that you can find on this link.
class AuthController < ApplicationController
  require 'auth_token'

  layout false

  def register
    @user = User.new(user_params)
    if @user.save
      @token = AuthToken.issue_token({ user_id: @user.id })
    else
      render json: { errors: @user.errors }, status: :unauthorized
    end
  end

  def authenticate
    @user = User.find_by(email: params[:email].downcase)
    if @user && @user.authenticate(params[:password])
      @token = AuthToken.issue_token({ user_id: @user.id })
    else
      render json: { error: "Invalid email/password combination" }, status: :unauthorized
    end
  end

  def token_status
    token = params[:token]
    if AuthToken.valid? token
      head 200
    else
      head 401
    end
  end

  private

    def user_params
      params.permit(:first_name, :last_name, :email, :password)
    end
    
end
Then, each time the client sends a request to the API, the token is being added to the header of that request. To do this, an interceptor is created on Angular side which intercepts each request and does this part of the job.
@topTalApp.factory('AuthInterceptor', ($location, $rootScope, $q, $injector) ->
  
  authInterceptor = {

    request: (config) ->
      token = undefined
      if localStorage.getItem('auth_token')
        token = angular.fromJson(localStorage.getItem('auth_token')).token
      if token
        config.headers.Authorization = 'Bearer ' + token
      config

    responseError: (response) ->
      if response.status == 401
        localStorage.removeItem 'auth_token'
        $rootScope.errorMsg = response.data.error
        $location.path '/login'
      if response.status == 403
        $rootScope.errorMsg = response.data.error
        $location.path '/'
      $q.reject response

  }
  
  authInterceptor

).config ($httpProvider) ->
  $httpProvider.interceptors.push 'AuthInterceptor'
  return
On the API side, the token is being extracted from the header of that request and checked whether it is valid (the expiration time is being set on the token). If it is valid than user_id is being used to get data for current_user. If token is invalid or there isn't any token, API returns http code 401 - which prevents unauthorized access to the API if someone is not authenticated...
module Api
  class BaseController < ApplicationController
    require 'auth_token'

    before_action :authenticate

    # jbuilder needs this
    layout false

    private

      def authenticate
        begin
          token = request.headers['Authorization'].split(' ').last
          payload, header = AuthToken.valid?(token)
          @current_user = User.find_by(id: payload['user_id'])
        rescue
          render json: { error: 'You need to login or signup first' }, status: :unauthorized
        end
      end

  end
end
And let's not forget about routes. This is how I defined routes. This is pretty straightforward but if you need some extra explanation about it you can find an excellent RailsCast episode about APIs.
Rails.application.routes.draw do
  root 'home#index'

  namespace :api, defaults: {format: :json} do
    resources :users, except: [:new, :edit]
    resources :expenses, except: [:new, :edit] do
      collection do 
        get :weekly
      end
    end
  end

  post '/auth/register', to: 'auth#register', defaults: {format: :json}
  post '/auth/authenticate', to: 'auth#authenticate', defaults: {format: :json}
  get '/auth/token_status', to: 'auth#token_status', defaults: {format: :json}

end

Authorization

Authorization is certainly another important thing in every application but unfortunately it is something that is not paying too much attention. Of course, everyone has their own idea of how authorization should be implemented and I don't think there is any general best practice but I think that this approach, which I applied here, is more than good. It is necessary to do authorization on the API side and also in the web application. On API side because calls can be directed only to an API without any application involved and within application users without enough permissions should be forbidden access to the certain parts of the application as well as the forms for inserting new data.
I defined three types of user in the application - regular user, admin and user manager. A regular user has permission to only list her expenses and to create them, user manager has the right to list all the users in the application, edit them and create a new one, admin has the right to create expenses for herself and to list and edit expenses of all users in the system as well as to create new and edit existing users.
class User < ActiveRecord::Base

  has_secure_password

  validates :email, :password_digest, presence: true
  validates :email, uniqueness: { case_sensitive: false }
  
  validates :password, length: { minimum: 5 }

  has_many :expenses
  
  belongs_to :role

  ROLES = {
    REGULAR: 1,
    ADMIN: 2,
    MANAGER: 3
  }

  def is_regular
    self.id_role == ROLES[:REGULAR]
  end

  def is_admin
    self.id_role == ROLES[:ADMIN]
  end
  
  def is_manager
    self.id_role == ROLES[:MANAGER]
  end

end

- Api

I didn't want to use Cancancan or Pundit or similar gems because I wanted to save myself some time and the authorization on the API is more than simple. All you have to do is to create a before_action filter and each controller then has to define who has the right to access the actions within it. If someone doesn't have permissions then you need to return http code :forbidden. This of course can't be tested in the application but there are tests you can write to check if everything is fine.
module Api
  class UsersController < Api::BaseController
    before_action :is_authorized?

    private

      def is_authorized?
        if @current_user.is_regular
          render json: { error: "Doesn't have permissions" }, status: :forbidden
          return
        end
      end

  end
end

- Angular

Angular part is a little more complex... First you should remove links from menu if certain user doesn't have permissions and then you should also disable the possibility for the same users to manually enter routes in the browser, which would allow them to visit those pages. It is pretty much easy to disable links in the menu but to do the other part you need to put some more effort in it. The most important part can be found in the file angular/services/auth.coffee:
@topTalApp.factory 'Auth', ['$http', 'CurrentUser', 'ROLES', ($http, CurrentUser, ROLES) ->

  currentUser = CurrentUser

  token = localStorage.getItem('auth_token')

  {
    isRegularUser: (user) ->
      user.getRole() == ROLES.REGULAR

    isAdminUser: (user) ->
      user.getRole() == ROLES.ADMIN

    isManagerUser: (user) ->
      user.getRole() == ROLES.MANAGER

    isAuthorized: (permissions) ->
      i = 0
      while i < permissions.length
        switch permissions[i]
          when 'REGULAR'
            return true if currentUser.getRole() == ROLES.REGULAR
          when 'ADMIN'
            return true if currentUser.getRole() == ROLES.ADMIN
          when 'MANAGER'
            return true if currentUser.getRole() == ROLES.MANAGER
        i += 1
      return false
  }

]
Then, you should listen to a $routeChangeStart event and disable access to a page if user doesn't have needed permissions. The code is in the file angular/app.coffee:
@topTalApp = angular.module('topTalApp', ['ngRoute', 'rails', 'templates', 'ui.bootstrap', 'sy.bootstrap.timepicker', 'angularUtils.directives.dirPagination'])

@topTalApp

  .run [
    '$rootScope'
    '$location'
    'Auth'
    ($rootScope, $location, Auth) ->
      $rootScope.$on '$routeChangeStart', (event, next, current) ->
        if next.access != undefined and !Auth.isAuthorized(next.access.requiredPermissionsAnyOf)
          if next.templateUrl == 'expenses/expenses.html' and Auth.isAuthenticated() != null
            $location.path '/users'
          else if next.templateUrl == 'expenses/expenses.html' and Auth.isAuthenticated() == null
            $location.path '/login'
          else
            $location.path '/'
        return
      return
  ]
  
  .config(
    ($routeProvider) ->
    
      $routeProvider
        .when '/signup', {templateUrl: 'sessions/signup.html', controller: 'SignupCtrl'}
        .when '/login', {templateUrl: 'sessions/login.html', controller: 'LoginCtrl'}

        .when '/', {
          templateUrl: 'expenses/expenses.html',
          controller: 'ExpenseCtrl',
          access: requiredPermissionsAnyOf: [ 'REGULAR', 'ADMIN' ]
        }

        .when '/expenses', {
          templateUrl: 'expenses/expenses.html',
          controller: 'ExpenseCtrl',
          access: requiredPermissionsAnyOf: [ 'REGULAR', 'ADMIN' ]
        }

        .when '/new_expense', {
          templateUrl: 'expenses/new_edit_expense.html',
          controller: 'ExpenseCtrl',
          access: requiredPermissionsAnyOf: [ 'REGULAR', 'ADMIN' ]
        }

        .when '/expense/:id', {
          templateUrl: 'expenses/new_edit_expense.html',
          controller: 'ExpenseCtrl',
          access: requiredPermissionsAnyOf: [ 'REGULAR', 'ADMIN' ]
        }

        .when '/expenses/weekly', {
          templateUrl: 'expenses/weekly.html',
          controller: 'ExpenseWeeklyCtrl',
          access: requiredPermissionsAnyOf: [ 'REGULAR', 'ADMIN' ]
        }

        .when '/users', {
          templateUrl: 'users/users.html',
          controller: 'UserCtrl',
          access: requiredPermissionsAnyOf: [ 'MANAGER', 'ADMIN' ]
        }

        .when '/new_user', {
          templateUrl: 'users/new_edit_user.html',
          controller: 'UserCtrl',
          access: requiredPermissionsAnyOf: [ 'MANAGER', 'ADMIN' ]
        }

        .when '/user/:id', {
          templateUrl: 'users/new_edit_user.html',
          controller: 'UserCtrl',
          access: requiredPermissionsAnyOf: [ 'MANAGER', 'ADMIN' ]
        }

        .otherwise({redirectTo: '/'})

  )
I think this is more than elegant solution for authorization. The whole code you can find on GitHub as I mentioned before.

Rails API

When you set up the basics of the application with authentication and authorization then you must set up the API part of the Rails. There is an excellent RailsCast about it and many tutorials online so I won't go into details. Of course, you can use Grape instead of Rails but I decided to stick with Rails because I've never before worked with Grape and I wanted to save time on this part too. The thing you have to keep in mind are the routes and the fact that each API call must return JSON response. You can use active model serializer or Jbulder or you can even go without that of course. But I used Jbulder because you definitely need an easy way to properly create JSON you want to return to the user that made the request. Again I have to mention that you have a great RailsCast episode how to use Jbuilder so I won't write on this topic further.

Angular app

This was a new ground for me, I've never built a SPA before but for two weeks how long did this project last I am very satisfied with what I've achieved. There are several ways to integrate your Rails API with Angular application. Again I chose the simplest option, although probably not the best. I used Angular gem. I think that in a bigger project the best way is to completely separate API part of its SPA part and not use this gem but in this situation it served the purpose really well.
I won't post pieces of the code here because you have a whole project on GitHub, but I would like to note that I used Slim for making templates, CoffeeScript instead of a plane JavaScript because I like cleaner code and I used Bootstrap too. I made a couple of filters in order to extract information about date and time from the column in the database that stores datetime together for nicer display. Everything else is pretty straightforward.

Timezone

The part of the project that I had the most headache is the part with printing data for expenses arranged by weeks. Why was this such a big problem? As I wrote in a previous blog post, it's very important how you work with time zones in your application. The best practice is to store everything in UTC time in the database. When a user enters a date and time in the form (her local time) you have to store that time in the UTC format in the database and then when you need to display that time to the user you have to convert it back into her local time. Pretty standard stuff... Except for one little thing - the requirement is to display expenses arranged by weeks and by weeks it's meant from the user's perspective. From user's perspective a week isn't the same as a week on the server which is in UTC time. So, you have to deal with UTC time because you have to prepare JSON response in your API but in the same time you have to deal with user's local time (starting and ending of the week) and arrange JSON response according to that. If a user is, for example, in Belgrade (CET) and if she inserts an expense for Monday, July 27th at 1 AM it would be 31st week of the year according to her. But by the server's time, it is Sunday July 26th at 11 PM, which means it is 30th week for the UTC time. I solved this problem by sending time zone offset as a parameter to the API and by adding it to a time I stored in the database. You must also pay attention to the edge cases when you calculate weeks when start of a week is in one year and its ending is in the next year.
def weekly
  expenses = findByDateFromAndTo params[:datefrom], params[:dateto], :asc
  my_json = {}

  add_minutes =  - params[:timezone].to_i.minutes

  expenses.each do |expense|
    year, month, week = (expense.for_timeday + add_minutes).strftime('%Y'), (expense.for_timeday + add_minutes).strftime('%m'), (expense.for_timeday + add_minutes).strftime('%V')
    year = (year.to_i + 1).to_s if month.to_i == 12 && week.to_i == 1
    key = year + '.' + week

    analytics = my_json[key] || {}
    analytics[:expense] = analytics[:expense] || []
    analytics[:total] = expense.amount + (analytics[:total] || 0)
    analytics[:items] = 1 + (analytics[:items] || 0)
    analytics[:start] = Date.commercial(year.to_i, week.to_i, 1).to_s
    analytics[:end] = Date.commercial(year.to_i, week.to_i, 7).to_s

    my_expense = {for_timeday: expense.for_timeday, amount: expense.amount, description: expense.description, comment: expense.comment}
    analytics[:expense].push my_expense

    my_json[key] = analytics
  end

  render json: my_json.values
end

TestS

Last but not least - tests! Writing tests is very important and you shouldn't neglect it even if you have tight deadline. I did lot more here than it was expected from me but unfortunately I didn't have time to write tests for JavaScript, but the procedure is pretty standard... I used Factory Girl and Faker to create data and also Database Cleaner to clean data after running tests.
FactoryGirl.define do

  factory :expense do
    
    association :user, factory: :user_regular

    amount { Faker::Commerce.price }
    for_timeday { Faker::Time.between(100.days.ago, 1.day.ago) }
    description { Faker::Lorem.sentence }
    comment Faker::Lorem.sentence

    trait :future_time do
      for_timeday { Faker::Time.forward(5, :all) }
    end

    factory :expense_future, traits: [:future_time]

  end

end
Next, you should write unit tests - tests for models, since this is not a big database there is only two models to test, user and expense:
require 'rails_helper'

describe Expense do

  it 'has a valid factory' do
    expect(build(:expense)).to be_valid
  end

  it 'is invalid without an amount' do
    expect(build(:expense, amount: nil)).to_not be_valid
  end

  it 'is invalid without a description' do
    expect(build(:expense, description: nil)).to_not be_valid
  end

  it 'is invalid without a time' do
    expect(build(:expense, for_timeday: nil)).to_not be_valid
  end

  it 'is invalid with a time set in the future' do
    expect(build(:expense_future)).to_not be_valid
  end

  it 'should belong to a user' do
    expense = build(:expense)
    user = build(:user)
    expense.user = user
    expect(expense.user).to be user
  end

end
And finally functional tests - for testing your controllers. I am especially proud of this part of the application since I covered entire API - authentication, authorization as well as creating expenses, users and so on...
require 'rails_helper'

describe AuthController do

  # because of the jBuilder I need to render views
  render_views

  describe 'POST #register' do

    context 'with valid credentials' do

      it 'returns user id' do
        #build a user but does not save it into the database
        user = build(:user_regular)
        post :register, { email: user.email, password: user.password, format: :json }
        expect(response.status).to eq 200
        parsed_response = JSON.parse response.body
        expect(parsed_response['user']['id']).to_not be_nil
      end

    end

    context 'with invalid credentials' do

      it 'does not have email' do
        post :register, { password: "pass", format: :json }
        expect(response.status).to eq 401
        parsed_response = JSON.parse response.body
        expect(parsed_response['errors']).to_not be_nil
        expect(parsed_response['errors']['email'][0]).to eq "can't be blank"
      end

      it 'does not have password' do
        post :register, { email: "email@email.com", format: :json }
        expect(response.status).to eq 401
        parsed_response = JSON.parse response.body
        expect(parsed_response['errors']).to_not be_nil
        expect(parsed_response['errors']['password'][0]).to eq "can't be blank"
      end

    end

  end


  describe 'POST #authenticate' do

    context 'with valid credentials' do

      it 'returns token' do
        user = create(:user_regular)
        post :authenticate, { email: user.email, password: user.password, format: :json }
        expect(response.status).to eq 200
        parsed_response = JSON.parse response.body
        expect(parsed_response['token']).to_not be_nil
      end

      it 'returns token with 3 parts separated by comas' do
        user = create(:user_regular)
        post :authenticate, { email: user.email, password: user.password, format: :json }
        expect(response.status).to eq 200
        parsed_response = JSON.parse response.body
        expect(parsed_response['token'].split('.').count).to eq 3
      end

      it 'returns first name and last name of the user' do
        user = create(:user_regular)
        post :authenticate, { email: user.email, password: user.password, format: :json }
        expect(response.status).to eq 200
        parsed_response = JSON.parse response.body
        expect(parsed_response['user']['first_name']).to eq user.first_name
        expect(parsed_response['user']['last_name']).to eq user.last_name
      end

    end

    context 'with invalid credentials' do

      it 'does not return token' do
        user = create(:user_regular)
        post :authenticate, { email: "no_" + user.email, password: user.password, format: :json }
        expect(response.status).to eq 401
      end

    end

  end

  describe 'POST #token_status' do

    context 'with valid token' do

      it 'returns OK code' do
        user = create(:user_regular)
        token = AuthToken.issue_token({ user_id: user.id })
        post :token_status, { token: token, format: :json }
        expect(response.status).to eq 200
      end

    end

  end

end
Again, the rest of the code you can find on GitHub :)

The end

If you are a great developer and you want to try yourself to do some similar project, and if you want to work for the Toptal as a freelance developer, to fulfill your dreams to work from home or some exotic island you can sign up here, I enjoyed participating in such a process of selection of candidates.
2 Comments

RAILS 4 + POSTGRESQL + TIMEZONE BEST PRACTICE

15/3/2015

1 Comment

 
Suppose we have a Rails application and we are using Postgresql as a database. There is always a question of what is the best way to deal with the time zones in this situation. In most cases that won't be of any importance, but if you have users from around the world and they need to know the exact point in time when something happened (banking transactions), then it is extremely important that you have time zones properly set in the application and on the server.

Prerequisite

Let's start with a simple create script that we want to execute on the database server (you could use migrations in Rails, but I want to have a full control over the database so I like it this way):
 
CREATE EXTENSION "uuid-ossp";

CREATE TABLE TESTINGS (
ID UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
NAME VARCHAR(500) NOT NULL,
DESCRIPTION VARCHAR(500),
TESTING_TIME_1_AT TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
TESTING_TIME_2_AT TIMESTAMP WITH TIME ZONE
);
Here we have two columns of type TIMESTAMP, you should always put your timestamp columns to be WITH TIME ZONE, there's no need to store time without time zone because you won't gain anything with it, but you could lose a lot even you don't need time zones. After you execute this script, you should create a model in your Rails application according to the table (testing.rb). Now let's begin to play with it.

Timezone on postgresql server

I suppose that you already installed your Postgresql server. If so, first you should check which time zone is set on the server with this command:
 
show timezone;
If the server isn't set to UTC time zone, you should do that by going to the file postgresql.conf. Locate timezone variable and change it to UTC (timezone = 'UTC'). Save the file, restart your server and check again with that command that the time zone is properly changed. By the way, this file is located under the path '\PostgreSQL\9.4\data' (if you have 9.4 version installed).
If, for some reason, you wish to configure different time zone on your server, be sure to set that same time zone inside your Rails application.

Timezone in rails application

In your Rails application, if you open file 'config/application.rb', you could see that the default time zone for the application is set to UTC, and you should leave it that way. But if you set different time zone on your Postgresql server, than you should set that same time zone in here. You can use this command to see which time zones are available in Rails:
 
$ rake time:zones:all
And this you can use to see the time zone which is set on your system, not in the application:
 
$ rake time:zones:local

Handling timezones

If you start your Rails console and type this:
 
$ test1 = Testing.create(name: 'Test1')
In your database you will create a data which will have for TESTING_TIME_1_AT current time in the UTC format, because previously you set your database to UTC and also you specified default value for this column. And if you do this:
 
$ test2 = Testing.create(name: 'Test2', testing_time_2_at: '2015-03-13 2pm')
You will create a data with TESTING_TIME_2_AT also set in the UTC format. But if you do this:
 
$ Time.zone = ActiveSupport::TimeZone.new('Belgrade')
$ test3 = Testing.create(name: 'Test3', testing_time_2_at: '2015-03-13 2pm')
You will change time zone in your Rails application so TESTING_TIME_2_AT will be set to time you entered but converted into UTC, because of the database, therefore '2015-03-13 13:00:00+00' if you do SELECT on the table.
Before we continue, one thing is important to notice. When one specific event occurs, time of that event is absolute, not relative, it's exactly one point in time. So if you have that point in time you can convert that time across different time zones. That's why it is important to store time zones in your database. If you don't do that, you won't have correct data when that event occurred because without time zone specified, that event might occur anytime during that day. If you have time in your database set to '2015-03-13 2pm' for example, you won't know what is the absolute time of that event regardless that hour of the day is entered. You won't know if that is London's time or Moscow's time...
You should try now to execute commands Time.now and Time.zone.now and you'll probably find yourself even more wondering what the hell is happening here. This is the explanation:
Time.now - gives you the time in system time zone, this is provided by Ruby and it doesn't know anything about our timezone configuration we just set.
Time.zone.now - is provided by Rails and gives you Time.zone value that we set in Rails.
Now type this:
 
$ test4 = Testing.create(name: 'Test4', testing_time_2_at: Time.now)
$ test5 = Testing.create(name: 'Test5', testing_time_2_at: Time.zone.now)
You might be surprised that inside your database you will get the same time for TESTING_TIME_2_AT in these two cases, not different one like you might think. This is fun, isn't it :) The catch here is that we set UTC time inside of the database and there is only one correct time IN THIS CURRENT MOMENT, not two, regardless which NOW method you use.
Since you are probably not in Honolulu, let's do this:
 
$ Time.zone = ActiveSupport::TimeZone.new('Pacific/Honolulu')
$ test6 = Testing.create(name: 'Test6', testing_time_2_at: Time.zone.parse('2015-03-14 8pm'))
Now when you select your data from the database, you'll get '2015-03-15 06:00:00+00' for TESTING_TIME_2_AT. That means that you inserted data with time zone from Honolulu and Postgresql converted it into UTC time which is 10 hours behind the UTC time zone. So when it's 8 pm in Honolulu on 14th of March, in London it will be 6 am on 15th of March, so we got everything right, we have exactly one point in time correctly inserted into our database.
Let's try something more here:
test6.testing_time_2_at = 'Sat, 14 Mar 2015 20:00:00 HST -10:00' - this gives time in time zone which is set in the Rails application.
test6.testing_time_2_at.localtime = '2015-03-15 07:00:00 +0100' - this gives time in local time zone, I am in Belgrade.
test6.testing_time_2_at.in_time_zone("Eastern Time (US & Canada)") = 'Sun, 15 Mar 2015 02:00:00 EDT -04:00' - you can convert time from database into any time zone you wish.

Wrap up

1) If you need to know a point in time when some event occurred then it isn't relevant what type of time zone you forward to the database because the database is set to the UTC time zone and it will always store time in UTC format, therefore you will have infallible data about time. The example is when you create a record in the database and time zone isn't important to the user of your application, you can forward Time.now or Time.zone.now to the database, it doesn't matter.
2) If it is important to store local time when user did some action to show it later to her, again it isn't important which time zone you forward to the database because in the database there will be set exact UTC time of that event. But when you need to show that time to the user, you need to convert it into local time for that user (for example, the time when some banking transaction occurred).
3) If user chooses a time inside of the application (for example you are building an application which sends some sort of notification to the users at the moment they defined), this is the case you need to take care of local time. Because if you don't do that, and user chooses time '2143-07-13 2pm', one day that distant year 2143 the user will receive the notification in the London timezone instead of the time that is valid in Honolulu. For this reason you need to forward to the database Time.zone.parse('2143-07-13 2pm'). It will be converted to UTC format and when you display that data to the user, you will manually convert that time into local time.
4) If you need to work on the procedures in the database, you'll always work with UTC time since every data is stored in UTC time zone, so no need to worry about converting into different time zones.

How to know the time zone of the user

One more thing you have to do to solve all problems with time zone settings is how to display that time for the user who uses your application. Since the time in your database is always in UTC format and your users can be anywhere in the world, you have to know the time zone of the person who uses your application. You can do that in two ways:
1) On the client side, using JavaScript or installing a gem that does that for you. Personally I don't like this way.
2) On the server side, take the user's location and based on that you can find the time zone. You can use gems like geocoder and timezone. Here you can have a problem if someone uses your application through a proxy, but these are borderline cases that doesn't happen often. Though if that can happen to you, in this case it is better to use client side approach with JavaScript because that data will be infallible (except if the time on that computer is incorrectly set).
Of course, you can always ask the user in a form to choose the time zone to which she belongs, so this information could be stored in the database as a user preference but that way the application loses quality because you ask a user something that you don't need to ask. This information can be obtained in a different way and thus free your user of unnecessary entries which drastically improves UX of your application.

The end

Certainly there are other ways how you can deal with time zones in your application, but I personally prefer to do it this way. However, if you work in this way or another, do not forget that the convention for working with time zones is very important when you build any application. You, as a developer, need to think of every single detail in the architecture of your system.
1 Comment

HIRING PROCESS IS COMPLETELY BROKEN!

9/1/2015

0 Comments

 
Since I am a software developer I get a lot of job offers through time and almost every time I got sick about the offer. Most often it goes something like this: "Hi, we find your resume is impressive and we think you could be great part of our team. You can look here (link) at our job offer and if you find it interesting let me know to put you through the hiring process." And what next? How that hiring process looks like? Something like 4 or 5 phases of the interview where you need to talk to psychologists, technical folks, managers... And you need to code some stupid algorithms like you didn't code any shit in the last 10 years. For God's sake, do you really think that I am a slave who will humbly do everything you can think of just to get any kind of work?
Picture
Working in a company should be pleasant, you need to feel there just like among friends and family. The most of your time you will spend at your work, not at home and staying in the office MUST be comfortable! Few years ago I got a job offer from Google when they sent me, before the first interview, 10 pages of materials that can be asked on the interview - practically everything that I learned in college for five years! Ok, I know that companies want to hire the best candidates, so through this idiotic tests they want to reduce the percentage of errors they can make by hiring someone, but asking a candidate to eat shit from the floor only to work somewhere is more than embarrassing.
Picture

THIS HAPPENS BECAUSE OF THE BAD MANAGERS.

When you want to meet your soul mate, a person with whom you want to build a friendly relationship that will last for years, with that person you go out for a date and try to establish a connection, pleasant conversation, to make sure that your time has passed pleasantly, because that would be an indication that you have a chance in the long run. When you meet with your soul mate you don't send him/her an email with a bunch of questions on 10 pages that you will ask on the first date. In this way, you can look for a prostitute. Send a list of things you expect from that person like blow job or something and if some of these things that person don't know to do you are not going to 'hire' him/her. What is the difference between renting a hooker and hiring process? This is not the 17th century and I am not working in an industry where I have to be happy and grateful if anyone offered me a job in my profession after a search that lasted two years.
Picture
I fucking have a choice and stop sending me job offers if you want to treat me like a prostitute! You need to have different approach, otherwise I will create my own job and hire people to work in my own company and I won't treat them like this when I need to hire them.
0 Comments

RAILS 4 + DATATABLES 1.10 + AJAX

10/12/2014

6 Comments

 
DataTables is a great tool which you can use to easily manipulate with tables in your web apps by adding pagination, sorting and searching through JavaScript. But if you need to manipulate with a table which has thousands of records you need to use server side processing and that can be a little difficult to accomplish in the right way. There is a great railscast episode about this but it's out of date since DataTables changed a lot since then. There is also a gem that you can use to solve this problem but it doesn't support Oracle and I had a hard time configuring it in a way that I needed to, so I decided to do it by myself from scratch but based on code provided in Ryan Bytes' episode.

A PROBLEM

Let's say you need to create an index page with products listed in a table with search bar on top and you need to use submitted search parameters to search for records in your database by product code and product name. Btw, I used Spawner Data Generator to generate enough records so I can test server side processing properly.
Picture

General information

For this purpose we will be using rails 4 with HAML, CoffeScript, Zurb Foundation as front-end framework, kaminari for pagination and Font Awesome for icons, so you need to configure your gemfile to include all of these. Don't forget to run 'bundle install':
 
source 'https://rubygems.org'

gem 'rails', '4.0.4' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'sass-rails', '~> 4.0.2' # Use SCSS for stylesheets
gem 'coffee-rails', '~> 4.0.0' # Use CoffeeScript for .js.coffee assets and views

gem 'jquery-rails' # Use jquery as the JavaScript library
gem 'jquery-ui-rails' # JQuery UI Library
gem 'jquery-datatables-rails' # Use datatables as default tables in the application
gem 'font-awesome-rails' # Icons

gem 'activerecord-oracle_enhanced-adapter', '~> 1.5.0' # Oracle database adapter
gem 'ruby-oci8' # Ruby interface for Oracle using OCI8 API
gem 'foundation-rails' # zurb foundation
gem 'simple_form' # Simple form builder
gem 'haml-rails' # Use haml processing in views
gem 'kaminari' # Pagination

gem 'turbolinks' # Turbolinks makes following links in your web application faster
gem 'jquery-turbolinks'

gem 'thin'
gem 'thin_service'
Also, don't forget to change your application.css and application.js files:
 /* 
*= require font-awesome
*= require_self
*= require foundation_and_overrides
*= require dataTables/jquery.dataTables.foundation

*= require_tree .
*/
 
//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require foundation
//= require dataTables/jquery.dataTables
//= require dataTables/jquery.dataTables.foundation
//= require turbolinks
//= require_tree .

Models

Let's assume we have Category model (code, name) and Product model (code, name, description, category), so Product model has one 'belongs_to' association and we need to put category name in product table on our index page. I won't post code that represents these models since there would be too much code in this post and it is very easy to code this.

INDEX page, CONTROLLER, ROUTES, JAVASCRIPT

Now let's get to the point... In your index page you need to wrap the header row inside a thead element and the body section in a tbody element. Nothing more than that since you are going to render records after you get them from the server. I added one additional column here - ID of the record which we won't display but it is fun to add more tricks to the code and you can later use it to select a row from a table and do something with it. Additionally, there is a search field where user can enter some text to search by product code or name. Later we will see how we are going to use this.
 
.row
.medium-12.columns

= form_tag products_index_path, method: 'get' do
.row
.medium-4.columns
%b Product code:
= text_field_tag :product_code, params[:product_code]
.medium-4.columns
%b Product name:
= text_field_tag :product_name, params[:product_name]
.medium-4.columns

.row
.medium-2.columns
= button_tag type: 'submit', style: 'color:#FFFFFF;', class: 'button tiny expand' do
%i.fa.fa-search.fa-lg
.medium-10.columns

.row
.separator

%br

.medium-12.columns

%table#product_table
%thead
%tr
%th{style: 'display: none'} ID
%th Code
%th Name
%th Description...
%th Category
%th
%th
%th
%tbody
Another thing we need to do in this step is to add some code to the controller and to configure routes:
 class ProductsController < ApplicationController 

def index

end

def datatable_ajax
render json: ProductsDatatable.new(view_context)
end
 Test::Application.routes.draw do 

resources :products

get 'products_ajax/datatable_ajax', to: 'products#datatable_ajax'

end
As you can see, the index action is empty. I didn't want to put code for fetching records for DataTables here since index action simply isn't for that. In index action you want to do something with the page in general and data in the page, for example fetch some other data besides data for the table. For that reason, we created separate action just for that purpose and that action will return just json, nothing else. The last thing in this step is to create products.js.coffee file where we can tell DataTables all information about the table and server side processing:
 $ -> 
product_table = $('#product_table').DataTable
processing: true
serverSide: true
ajax:
url: '/products_ajax/datatable_ajax'
data: (d) ->
d.product_code = $('#product_code').val()
d.product_name = $('#product_name').val()
return
columns: [
{ width: "0%", className: "dont_show", searchable: false, orderable: false }
{ width: "15%" }
{ width: "35%", className: "row_config" }
{ width: "null", className: "row_config", searchable: false, orderable: false }
{ width: "null", className: "row_config", searchable: false, orderable: false }
{ width: "5%", className: "center", searchable: false, orderable: false }
{ width: "5%", className: "center", searchable: false, orderable: false }
{ width: "5%", className: "center", searchable: false, orderable: false }
]
order: [ [1,'asc'] ]
You can arrange your columns as you wish, I did it in this way. There is a class name for the first column since we don't want to display column with ID, so you need to add some CSS in here, for example in products.css.scss file. 'row_config' class name tells to each table cell that if content in that cell is too long, the content won't be broken in additional lines - the content will be displayed in that cell as is, with dots (...) if content is longer. In that way you keep your table well formatted.
 
.row_config {
max-width: 200px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}

.dont_show {
display: none;
}
One more thing - we will send additional parameters via DataTable using this 'data' part, You can send as much additional parameters as you like. So, when you perform some action on the table, DataTables will collect other information from the page and send them to the url you defined.

AJAX PART

And finally, here is the main part of the application. In this section we will perform everything needed to fetch, prepare and display data in a proper way:
 class ProductsDatatable 
delegate :params, :fa_icon, :link_to, :products_path, :edit_products_path, to: :@view

def initialize(view)
@view = view
end

def as_json(options = {})
{
data: data,
recordsTotal: my_search.count,
recordsFiltered: sort_order_filter.count
}
end

private

def data
products = []
display_on_page.map do |record|
product = []
product << record.id
product << record.code
product << record.name
product << record.description
product << (record.category.present? ? record.category.name : '')
product << link_to(fa_icon('info-circle lg'), products_path(record), class: 'label success round')
product << link_to(fa_icon('edit lg'), edit_products_path(record), class: 'label secondary round')
product << link_to(fa_icon('trash-o lg'), products_path(record), method: :delete, data: { confirm: 'Are you sure?' }, class: 'label alert round')
products << product
end
products
end

def my_search
@filtered_products = Products.filter_product_code(params[:product_code]).filter_product_name(params[:product_name]).some_additional_scope.distinct.includes(:category)
end

def sort_order_filter
records = my_search.order("#{sort_column} #{sort_direction}")
if params[:search][:value].present?
records = records.where("PRODUCTS.CODE like :search or lower(PRODUCTS.NAME) like :search", search: "%#{params[:search][:value]}%")
end
records
end

def display_on_page
sort_order_filter.page(page).per(per_page)
end

def page
params[:start].to_i/per_page + 1
end

def per_page
params[:length].to_i > 0 ? params[:length].to_i : 10
end

def sort_column
columns = %w[not_orderable PRODUCTS.CODE lower(PRODUCTS.NAME) not_orderable not_orderable]
columns[params[:order][:'0'][:column].to_i]
end

def sort_direction
params[:order][:'0'][:dir] == "desc" ? "desc" : "asc"
end
end
This file is too long to explain every single detail, but you can use railscast episode as a guide. Also, you can notice that you need to define scopes in your Product model class and use it to filter data according to the parameters submitted by the user. The scope can be defined in this way for example:
 scope :filter_product_name, -> (product_name) {where("lower(PRODUCTS.NAME) like :search", search: "%#{product_name.downcase}%")} 
You maybe noticed that I use LOWER function a lot. It's Oracle's function you can use to down-case your string, so search can be performed regardless of the way user entered search parameter. You can also use this when you specify sort columns as shown above. I am not sure if you can customized your searches and sorts in this way using gem I mentioned in the beginning.

THE END

I hope this helps a little. It's pretty easy to configure your table with DataTables if you know the basics, but for beginners it can be really hard to collect all the pieces and make a functional solution.
6 Comments

RAILS 4 + HAS_MANY THROUGH + FOREIGN KEYS + SCOPE

10/10/2014

0 Comments

 
If you are dealing with a legacy database with weird names of tables and keys that don't follow rails practice for table naming than you will probably have a problem figuring out how to connect all the dots of your application. On top of that if you have to deal with "many-to-many" relation than you have a real tough task to accomplish. So let's go over one example how you can deal with this problem with ease.

A PROBLEM

Let's say you have a database table 'A(ID)', a table 'B(ID)' and a table 'AB(ID, ID_A, ID_B)'. 'A' has many of B's and 'B' has many of A's so 'AB' is a join table. You have to create models with the same names as database tables (in rails your database table name should be plural and your model should be singular so this is one more problem for you). And on top of that you need to create a scope in model 'A' to get data from table 'A' but you need to use some columns from table 'B'. For example (just to make you clear what we need to do) you have patients, physicians and appointments. And you have to find all physicians that have patients born in 1974. So in our example in table 'B' you would have one more column 'REQUIRED_YEAR'.

MODELS

Now that we defined our problem we can start developing our models:
Picture
Picture
Picture
As you can see, there are a lot of tricks in here, so be careful about every single line of code. Regardless of the rails naming conventions I always put 'class_name', 'foreign_key' and 'primary_key' options when I define a has_many or belongs_to associations. Maybe it's a few extra characters of code but I feel a lot safer not thinking what rails is doing 'under the hood' connecting names of the associations with model names.

A SCOPE

And finally let's create a scope in 'ModelA' to get all the data from table 'A' where a record from 'A' is connected to 'B' through 'AB' with a required year of 2012. Next image is a complete 'ModelA':
Picture
Now from console you can simply call:
Picture
Corresponding SQL query that is generated:
Picture

THE END

And that's it - pretty simple if you know the basics. I hope this can save you some time coding.
0 Comments

Alanya, Turkey - Guide

20/9/2014

0 Comments

 
I recently got back from Alanya (Turkey) where I spent 10 days on holiday and I decided to write a text about this place which might serve as a guide to people who want to visit and spend some time here. Since I am a big fan of the work out of the office, if you are able to work from anywhere in the world, I will give an overview of how this place would suit for digital nomads.
Alanya

LOCATION

Alanya is on the southern coast of Turkey, 138 kilometers (86 miles) east of the city of Antalya. It is located just about 250 km from Cyprus. The town is situated between the Taurus Mountains to the north and the Mediterranean Sea, which is very important to note because of the characteristic climate here.

WEATHER

Let's start with the weather. The waiter who works here told me that season last for almost 6 months, although from the beginning of September is emptier since the school starts in Turkey and all around the Europe. By the way, the waiter came to work here from Kyrgyzstan because, as I heard, they can earn a lot of money during the summer just working as waiters. I was here in the beginning of September and it was warm, not too much for my test, around 30 C. The problem (for many people, but not for me) is humidity. It is extremely high, so it might be 25 C outside but the feeling is like it is 35 C. I am fine with that but I heard from a lot of people that it can bother them. Like I mentioned, the city is located between the mountain and the sea so all warm air coming from the sea stays here and doesn't go up north.
Picture

City and the beach

The city is just beautiful, not too much big, but not small to be boring. You have one long main street with a lot of restaurants, bars, shops, supermarkets, hotels... In the city center you can find a lot of clubs so be careful when you chose your hotel since we had to walk every night 2 km just to get to city center where all the parties are located. It can be really hard to walk back to the hotel in the 3 am... 
Picture
The beach stretches along the entire Alanya, with one important remark: the best beach is the Cleopatra beach. Again I have to mention that you should carefully choose your accommodation because our hotel was located 45 minutes walk from this beach. We had a nice beach just across the hotel (see next picture) but it wasn't so beautiful and well-organized as Cleopatra's.
Picture
Of course, since this is the main beach in the city, it is always full of people, I believe particularly in July and August, so if you do not like crowd then you might be more convenient to choose a hotel away from this beach and to swim at some more isolated place. You won't find shades anywhere on the beaches, so you can stay in the hotel and go to the beach when you want to take a swim, you can burn in the sun or you can rent a beach sunbed and/or sunshade. To rent a sunshade for a day will cost you about 4, 5 Turkish lira which is about one and a half euros (you can bargain).
Picture
Since lunch time in our hotel was in a bad time for us (from 12h till 14h), time until the lunch we spent at the hotel pool and after lunch we went to Cleopatra beach by public transport (15 minutes) where we rented only sunshades without sunbeds.
Picture

People

This is a secular Muslim country - so don't be afraid. It's like any other country in Europe, people watching TV, going out, having fun... The only difference here is that Turkish people don't drink (so much) alcohol as other nations in Europe so alcohol drinks are very expensive here. When you go into the supermarket, prices are reasonable so no need to worry about that. When you want to buy something in local shops like souvenirs, clothes - you can bargain with the owner and get some good price, it is very common around here.
Picture

Hotel, Food and drinks

Like I said - alcohol drinks are expensive. You can buy a beer in local supermarket for 5 lira which is around 2 euros. If you go out, beer in a club is around 7, 8 euros and if you are fancy for a cocktail you need to pay 25 to 30 liras, around 10 euros.
Picture
Food is more than ok, I really liked it. Since I am from Serbia, we have very similar dishes. Maybe a little more greasy for my taste but fine. Regarding meat, you can mainly find chicken meat around here. Fish also but you should definitely try Turkish kebab. It is similar to Greek gyros or the Middle Eastern shawarma. And of course - Turkish delights, all sorts of sweets... Try baklava, rahat lokum... If you want to bring something home to your friends or family, I highly recommend you to buy these delights - you can buy for example 2 kilos of these delights for 40 euros. You can put it in 4 boxes and you have 4 presents you can bring to someone.
Picture
About the hotel, we booked a room in Elysee hotel - I was not so much happy about our choice. Like I said, our hotel was 30 minutes from city center, 45 minutes from Cleopatra beach and we needed to walk or to take a bus every day. Besides that, the hotel was fine, it was clean, but not very new. We had all inclusive service - breakfast (7h-9h), late breakfast (9h-10h) - pretty much nothing good to eat except eggs in all sorts of form. Launch (12h-14h), dinner(19h-21h) and some snacks in the middle. You can have soups, main dishes, salads, sweets, drinks (beer, wine, vodka, whiskey, gin, Pepsi, Fanta, Sprite) all you can eat and drink. But be careful, on fourth day in Alanya I started having stomach problems and next 4 days I struggled with that. And I didn't drink local watter, just bottled and didn't eat anything outside the hotel!! I guess you can have stomach problems in any hotel in Alanya. My friends didn't have any trouble so I guess that fresh green salad was making problem to me...
Picture

Night life

Since we visited Alanya in September, it wasn't so crowded and clubs were pretty empty, but it was ok in general. If you want to drink some good cocktail I recommend you visit Crazy Horse bar. If you like clubbing I recommend you visit Havana or Robin Hood - the club on three floors, on the last one is Latino stage with great music. Besides that you can visit some local restaurants, but since we had all inclusive service we didn't try anything of that sort. The city center, on the other hand, is crowded all day and all night and you can find a dozens of clubs and bars in that small area around center. There is also a police station in the very center so I think that you can be more than safe to walk around in late hours if you are afraid of some drunk people.
Picture

AIRPORT and public transport

Antalya is a very large city and there is an international airport with some great local carrier like Onurair. They are flying to Amsterdam for example and some other major cities so it's not a problem to get here. From the airport to Alanya you can take a bus which will cost you 10-15 euros. You can find buses everywhere in front of the airport. Regarding public transport, the main bus lines are 1 and 101 which can transport you through the main street. The ticket is 2 lira (little less than 1 euro) and you can pay it to the bus driver when you enter the bus on the front door. You won't get any receipt for paying ticket.
Picture

For digital nomads

Overall, I think Alanya is a great place to visit and to be in for a couple of months. The weather is beautiful, with no rain, you have a great beach, night life is also fine. And it's not expensive. Regarding the Internet connection, we had it in the hotel lobby and by the pool and you can pay extra if you want to use it in your room. I don't know if there is any co-working places in the city so I am not sure where you can find some office to work in. You have also a cinema in the city (I don't know if there are movies on English, there are on Russian though). So if you are from Europe, USA, Canada and Thailand is too far away and exotic for you - try Turkey and give a chance to Alanya, I think you will enjoy staying here.
Picture
0 Comments

RAILS 4 + ORACLE

19/9/2014

0 Comments

 
Quick and dirty setup.

Oracle gems

First you need to install few necessary gems, so put this code in your GEMFILE:
Picture

database.yml

Next, you need to edit this file, something like this:
Picture
This is a little bit different than configuring your postgres database since you define here a user that will be used as a database name, so you don't need to enter a database name separately, you need to put your SID under 'database' entry.

Oracle user

Since you configured your database.yml file like this, you need to manually create new user in your oracle database and that user will be 'testing'. Go to SQLPlus, log in as an admin and type this:
Picture
You created your user and now you need to grant him some privileges:
Picture

THE END

Now you do all that 'rake db:migrate' shit but there's no need to do 'rake db:create' too, since this is ORACLE, and ORACLE has to be different and special :)
0 Comments

RAILS 4 + HAML + ZURB FOUNDATION 5 + SASS + POSTGRES

21/8/2014

1 Comment

 
Hello again. It's been awhile since I wrote something but I am too busy building my startup Warrantly so I really don't have time to write often. Nevertheless, now it's time to share something new. Being a Java developer for years I switched to Ruby on Rails a year ago because we decided it could be the best tool to build a startup. Boy it was a great decision! Since then I am really enjoying exploring Ruby and Rails and I don't have any desire going back to Java again.
Picture
Don't get me wrong, Java is a great programming language but with Rails you can create a new functional website in literally minutes! And with Java you have to decide which framework to use, how to connect everything to work properly and you will spend hours figuring out that. A year and a half ago I wrote how to start a new project with Spring because it is too complicated and I wanted to write down few steps you need to do to connect everything to work properly. Now I will show you how to do the same thing with Rails and it is so damn simple you will need only 15 minutes.

PREREQUISITE

First you need to install Ruby and Rails 4 and you can find tutorials everywhere how to do that so I won't explain that part. You don't need any IDE to code your program, you can use any text editor (I prefer Sublime) and you'll need a console. Now it could be a little more complicated if you are using Windows but it won't make you some serious trouble.

CREATE NEW APP AND ADD GEMS

In your console, go to the directory you want to use to store your project and type this:
Picture
And you created your app! Next step is to add gems: foundation-rails, sass-rails, haml-rails, pg (for Postgres database) and add simple_form because I highly recommend using it in your app.
Picture

CONFIGURE DATABASE

If you want to connect your project with a database then you need to configure your database.yml file located under config directory:
Picture

ZURB FOUNDATION + HAML

Since we are using ZURB and HAML now you need to go to your console again and run this line:
Picture
We are installing Foundation and overriding application layout file under view directory because we want to use HAML. Now under assets/stylesheets directory find the file application.css and rename it to application.scss. You don't need to do that but if you want to use sassy css in your whole app it is good practice to do this in this step. By the way, you are probably asking what the hell are sass and scss, are they the same thing or not? I won't explain here more on this subject but you can find great explanation about them in one railscast episode.

SIMPLE FORM

Installing simple form gem is also one liner:
Picture

ScafFold + DATABASE MIGRATION

This was really skinny tutorial but I don't want to write 5 pages long post about simple stuff. Basically the application is ready to use. You can now create model, views, migration files just using one rails command, the powerful scaffold:
Picture
In your migration file which is created with this command (under db/migrate) you can add some code, this for example:
Picture
To reflect these changes to your database you need to run three commands:
Picture
Picture
Picture
With these commands you created actual database, load you schema, populated it with some seed data (if you have any under seeds.rb file) and ran your migration file to create a database table. Find more about these commands, you will need them during your development.

THE END

I hope this can help you like my previous post about SPRING did it. If you plan to launch some startup, maybe Rails is the right tool for you.
1 Comment

WARRANTLY

5/6/2013

0 Comments

 
Picture
Yes it's true - I founded a startup! This is the reason why I neglected writing a blog for last couple of months. So, in the future, I'll write mainly on startup topics. For months now I tried to think of a good idea for sturtup. After couple of very bad ideas and couple of less bad ideas but not good enough, I finally got the right one. During the last couple of months this idea evolved into well structured product. There are 5 guys in the team, we are almost at the end of building our MVP and we are already in the talk with few companies that are interested in using this software. In the next couple of lines I'll describe what we are building.

Warrant.ly is a system that allows retailers to issue online warranties to customers instead of paper ones. In this way, all problems that may occur with the purchased device within the warranty period can be easily solved through the website. The customer will report the problem to the retailer and they can arrange the repair easily through the website as well. The customer will also be able to check its status. What is more important to the customers, they will be able to keep their warranties in this system even though they were issued the old-fashioned way – in a paper form. The customer just needs to enter basic information about the device and to take a picture of the warranty.
Picture
This is just a basic description, retailers will get much more possibilities in this software so they can really improve their business. They can create and offer extended warranty plans to their customers and also send some offers about specific devices to targeted users.

We already presented our startup to some investors. We attended mini Seedcamp event in Belgrade in April and we got very good feedback although we didn't manage to get into Seedcamp program. Also, some other startup incubators in the region contacted us about possibilities of joining them. We'll see what's the best option for us at the moment.

That's it for now, come back soon on this site to find more news about this startup and startups in general. And of course, if you are a retailer and you are interested about possibilities our software offers, please contact me. I guarantee that your business can only improve and progress by using Warrantly.
0 Comments
<<Previous

    Nikola Todorovic

    Software developer from Belgrade, founder of Warrantly.

    Archives

    December 2015
    August 2015
    March 2015
    January 2015
    December 2014
    October 2014
    September 2014
    August 2014
    June 2013
    December 2012
    November 2012

    Categories

    All
    Ajax
    Angular
    API
    DataTables
    Hibernate
    Holiday
    Maven
    Metaprogramming
    Mysql
    Oracle
    Postgres
    Rails
    Ruby
    Sea
    Software
    Spring
    Startup
    Tomcat
    Turkey
    Website

    RSS Feed

Powered by Create your own unique website with customizable templates.