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.

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:

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:

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.

Inside class methods, self refers to the class itself in a way (which will be discussed in more detail later in this article):

classDeveloperdefself.backendselfendendpDeveloper.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:

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 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:

classDeveloperdefself.backend"I am backend developer"endend

This is a basic definition that almost everybody uses.

defDeveloper.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.

classDeveloperclass<<selfdefbackend"I am backend developer"endendend

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<<Developerdefbackend"I am backend developer"endend

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:

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:

classObjectdefmetaclass_exampleclass<<selfselfendendend

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:

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:

pdeveloper.class.singleton_class.instance_methodsfalse# [: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:

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:

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:

classDeveloperdefine_method:frontenddo|*my_arg|my_arg.inject(1,:*)endclass<<selfdefcreate_backendsingleton_class.send(:define_method,"backend")do"Born from the ashes!"endendendenddeveloper=Developer.newpdeveloper.frontend(2,5,10)# => 100pDeveloper.backend# undefined method 'backend' for Developer:Class (NoMethodError)Developer.create_backendpDeveloper.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:

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.

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.

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.

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.

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...

Authoriza﻿tion

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.

- 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.

moduleApiclassUsersController<Api::BaseControllerbefore_action:is_authorized?privatedefis_authorized?if@current_user.is_regularrenderjson:{error:"Doesn't have permissions"},status::forbiddenreturnendendendend

- 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:

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.

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.

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'describeExpensedoit'has a valid factory'doexpect(build(:expense)).tobe_validendit'is invalid without an amount'doexpect(build(:expense,amount:nil)).to_notbe_validendit'is invalid without a description'doexpect(build(:expense,description:nil)).to_notbe_validendit'is invalid without a time'doexpect(build(:expense,for_timeday:nil)).to_notbe_validendit'is invalid with a time set in the future'doexpect(build(:expense_future)).to_notbe_validendit'should belong to a user'doexpense=build(:expense)user=build(:user)expense.user=userexpect(expense.user).tobeuserendend

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'describeAuthControllerdo# because of the jBuilder I need to render viewsrender_viewsdescribe'POST #register'docontext'with valid credentials'doit'returns user id'do#build a user but does not save it into the databaseuser=build(:user_regular)post:register,{email:user.email,password:user.password,format::json}expect(response.status).toeq200parsed_response=JSON.parseresponse.bodyexpect(parsed_response['user']['id']).to_notbe_nilendendcontext'with invalid credentials'doit'does not have email'dopost:register,{password:"pass",format::json}expect(response.status).toeq401parsed_response=JSON.parseresponse.bodyexpect(parsed_response['errors']).to_notbe_nilexpect(parsed_response['errors']['email'][0]).toeq"can't be blank"endit'does not have password'dopost:register,{email:"email@email.com",format::json}expect(response.status).toeq401parsed_response=JSON.parseresponse.bodyexpect(parsed_response['errors']).to_notbe_nilexpect(parsed_response['errors']['password'][0]).toeq"can't be blank"endendenddescribe'POST #authenticate'docontext'with valid credentials'doit'returns token'douser=create(:user_regular)post:authenticate,{email:user.email,password:user.password,format::json}expect(response.status).toeq200parsed_response=JSON.parseresponse.bodyexpect(parsed_response['token']).to_notbe_nilendit'returns token with 3 parts separated by comas'douser=create(:user_regular)post:authenticate,{email:user.email,password:user.password,format::json}expect(response.status).toeq200parsed_response=JSON.parseresponse.bodyexpect(parsed_response['token'].split('.').count).toeq3endit'returns first name and last name of the user'douser=create(:user_regular)post:authenticate,{email:user.email,password:user.password,format::json}expect(response.status).toeq200parsed_response=JSON.parseresponse.bodyexpect(parsed_response['user']['first_name']).toequser.first_nameexpect(parsed_response['user']['last_name']).toequser.last_nameendendcontext'with invalid credentials'doit'does not return token'douser=create(:user_regular)post:authenticate,{email:"no_"+user.email,password:user.password,format::json}expect(response.status).toeq401endendenddescribe'POST #token_status'docontext'with valid token'doit'returns OK code'douser=create(:user_regular)token=AuthToken.issue_token({user_id:user.id})post:token_status,{token:token,format::json}expect(response.status).toeq200endendendend

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.

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):

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:

showtimezone;

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:

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.

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.

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.

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.

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':

gem'jquery-rails'# Use jquery as the JavaScript librarygem'jquery-ui-rails'# JQuery UI Librarygem'jquery-datatables-rails'# Use datatables as default tables in the applicationgem'font-awesome-rails'# Icons

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.

Another thing we need to do in this step is to add some code to the controller and to configure routes:

classProductsController<ApplicationController

defindex

end

defdatatable_ajaxrenderjson:ProductsDatatable.new(view_context)end

Test::Application.routes.drawdo

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:

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.

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:

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

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.

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:

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':

Now from console you can simply call:

Corresponding SQL query that is generated:

THE END

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

Oracle gems

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

database.yml

Next, you need to edit this file, something like this:

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:

You created your user and now you need to grant him some privileges:

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 :)

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.

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:

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:

ZURB FOUNDATION + HAML

Since we are using ZURB and HAML now you need to go to your console again and run this line:

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:

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:

In your migration file which is created with this command (under db/migrate) you can add some code, this for example:

To reflect these changes to your database you need to run three commands:

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.