📜 ⬆️ ⬇️

Let's beat Ruby together! Drop thirteen

Today we will get acquainted with such a powerful and useful Ruby tool and RoR component, like Active Record. As part of RoR, we know Active Record from the first step of articles on rails (something this series didn’t go very well, really). Consider the practical use of the component in Ruby, which is very useful in RoR.

Active Record adheres to the principles of ORM : databases can be represented as object-oriented code, where tables are classes, rows of a table are objects, and fields are object attributes. However, Active Record differs from other ORM libraries, for example, from Hibernate from Java , in that there is no need for an initial configuration - everything works out of the box. Active Record is written in pure Ruby, which allows us to work with it as with a normal class: use inheritance, rewrite methods, use metaprogramming, etc. Yes, object attributes are mostly filled with SQL queries and the attributes are also written back to the table. But all that happens between these two processes is the usual work with the Ruby object. It is necessary to understand the "separate" existence of database records and Ruby objects: sometimes the database will be different from the Ruby class.

When you create a new record in the database, update an existing one or simply read the data, everything goes in three steps: creating an Active Record object, accessing and manipulating the object's attributes, and saving the attributes as records in the database.

Installing Active Record


As usual in Ruby, installation is a trifling matter; it is enough to install the necessary jam: gem install activerecord . Connecting to the database occurs with the help of adapters, most of which are already embedded ( DB2, Firebird, FrontBase, MySQL, Open-Base, Oracle, PostgreSQL, SQLite, SQL Server and Sybase ), you only need to transfer the connection parameters to the database. You should also make sure that you have installed / running a database server and installed the necessary jam ( mysql or sqlite3-ruby , for example).
')

In use



Let's start with the following Accounts:
id (integer; auto-incremented; primary key)
username (text)
password (text)
table Accounts:
id (integer; auto-incremented; primary key)
username (text)
password (text)
Accounts:
id (integer; auto-incremented; primary key)
username (text)
password (text)


First of all, we connect to the database:

require "rubygems"
require "activerecord"

ActiveRecord::Base . establish_connection (
:adapter => "mysql" ,
:host => "localhost" ,
:username => "user" ,
:password => "pass" ,
:database => "project_development" )



As you can see, to do this, you must pass the parameters in the form of a hash to the establish_connection method. For SQLite, only :adapter => "sqlite" and :database are needed.

In accordance with the table we create a class-successor:

Class Account < ActiveRecord::Base
end



Here you should pay special attention to the name of the class. As usual, the principle of conventions over configuration, according to which the name of the table in the plural, the name of the class - in the singular, works here. You can, of course, bypass this limitation, but you should not do it - work in the Ruby / Rails way, and you will understand how convenient it is.

So, as we know, to create an entry in the table, we have to work with Ruby objects. To create a new row in the Accounts database, create an instance of the Account class using the standard new method:

acc1 = Account. new
acc1. username = "maxelc"
acc1. password = "maxspassword"



Here we see one of the key advantages of Ruby - metaprogramming. For us, methods with the same table columns were created for us to edit the attributes of the instance. Very convenient, but this is only the beginning, more - more. However, this is only an instance of a class, the table has not yet changed (as mentioned above). To “synchronize” the instance with the table, creating a new line, use the save method:

acc1. save


Another way to make an entry:

acc2 = Account. new (
:username => "hbuser" ,
:password => "habrapass" )
acc2. save



We have learned to keep records, now we need to extract them. We understand that in this case we must create an instance of the class and fill it with attributes from the row of the table. In fact, it is easier. If we know the id string, we use the built-in (core) method of find :

result1 = Account. find ( 1 )



Quite trivial, but what if we want to search by columns / attributes? Here Ruby’s metaprogramming framework comes to our rescue again - we use dynamic search methods:

result2 = Account. find_by_username ( "hbuser" )


This is a small piece of the magic that Active Record provides for us - again the methods were generated for us on the fly. I think that the structure of their names is clear. Example more abruptly:

result3 = Account. find_or_create_by_username ( "superuser" )


And in this case the name of the method speaks for itself: “find or create a username”. Accordingly, if an element is searched for (we say an element - we mean a table row, but in fact it is), the search condition will not be found, then it will be created and saved in a table ( save not needed in this case).

So, we created the necessary instance / line, found it, and now we are looking at how to update the data and delete it completely:

Account. update ( 1 , { :password => 'newpass' } )
puts " "
Account. delete ( 2 )



It is worth noting here that, despite the fact that we have deleted a row from the database, the instance continues to exist read-only until the instance itself is directly deleted or goes out of scope (scope is a separate topic).

Active Record Connections



Communication between objects is not only an incredibly important part of the Active Record functionality, it is simply necessary in real applications. There are several types of links, we will consider one.

Now we want to associate with each user a specific group, like Administrator or Guest. To begin with, we will create a Groups table containing id and name (groups). You also need to add a new group_id column to the Accounts table for use as a foreign key (the naming conventions work again). In our case, you can think of the connection as “each account has a role”. For this kind of links, the belongs_to method is belongs_to . But first, create a new class for Groups in our script:

class Group < ActiveRecord::Base
end



We must define the connection in the class Account , by adding the class like this:

class Account < ActiveRecord::Base
belongs_to :group
end



Now we have one-way communication - the account knows that it has a group, and the group does not know about its accounts. Let's create a group of administrators and assign an account to it:

admin_group = Group. find_or_create_by_name ( "admin" )
account. group = admin_group
account. save



As you can see, for the class Account, a new method has emerged that records a group for it. We simply “equated” the attribute (not really an attribute, but for the end user it looks like this) of the account to the entire group instance, Active Record understands this by doing what we need.

Epilogue



Here is an introduction to this powerful system. First of all, it will, of course, be used when working with web applications, Rails, in particular. If you have a desire, then we can go deeper into Active Record or, for example, Rake. As usual - comments and comments are welcome at the highest level;)

Source: https://habr.com/ru/post/51943/


All Articles