## Friday, 7 March 2014

### ActiveLeonardo: create a Rails 4 application with Ruby 2 and ActiveAdmin

In a previous article I described step by step how to create a managerial in few minutes with my generator ActiveLeonardo which uses ActiveAdmin. Actually it generates little code and could be called an assembler.

Since then there have been many innovations: rails 4 was released, we got to the 2.1.1 version of ruby and also the project ActiveAdmin, despite an initial period of torpor, is in full swing for some improvements but mainly to make it compatible with the latest version of the famework.

I was just waiting to find the time to update the project and with the help of a my colleague I finally released the new version.

We're using it for all new projects. The advantages of such a system are many:

• Standardize corporate projects: uniform layout and structure.
• Centralize in a single point the changes of its own standard.
• Select the best gems or the best strategies that populate the web.
• Quickly create a new application and rapid integration of new functionality to an existing one.
• Easy maintenance.

However it should be considered the alteration of the functioning of rails going from mvc pattern to a model view, the controller is in fact hidden. It 'an incentive to encapsulate logic in the model as required by good practice although there remains the possibility to access controller methods or extend it with new ones.

The new version has been tested with:
• Rails 4.0.3
• Ruby 2.0
• Windows

It works in the same way as the previous version so you can use the previous tutorial.
That version of ActiveAdmin is not present on Rubygems and you must use the source on github. The new active template has been set up and you should have no problems.

The new template has been completely revised and is constantly evolving. We tried to limit the questions by grouping gems by type. You may consider also this a starting point for creating your customized version.

The development took place on windows and for the moment the only os tested. The most obvious improvement is undoubtedly linked to the speed, now finally also on this os start up and run times are good, in line with those of rails 2. As soon as possible we will test the other os and version 2.1 of ruby.

The new version of Active Admin introduces some changes to an interface that already was great: easy to use and to customize.

## Monday, 20 August 2012

### Create a management app in few minutes with active admin and rails 3.2

ActiveLeonardo let you create a management application from scratch in few minutes.

The generator is not intended to churn out the finished product but provides a basis from which to start. It creates the skeleton of the application which will cut out a dress and as we know a nice dress should be tailored by hand.

The achievement is remarkable and I recommend you give it a try.

On github there is a short tutorial and here I show you a more descriptive guide to clarify its potential.

I can summarize with this three simple steps:
1. Create the new app
2. Adding resources (information to manage)
3. Starting the web server, the end!

You choose the name, you define the resources, all the remnant is a load of your PC.
My Windows 7 laptop with a second generation i7 and a 7200 rpm hard use about 1 minute. With a desktop and a SSD the operation is almost instantaneous. In any case the generator will create all the necessary in very little time and with minimum effort.

I will create a container of information in this case a rudimentary issue tracker (but could also be a recipe book, a blog, etc..) So we start by creating the application LeoTicket:

rails new LeoTicket -m dl.dropbox.com/u/52600966/active_template.rb

To accept the proposed sections just answer y. I suggest you add everything to better follow this tutorial.
The template allows you to add some basic gem for handling authentication, the permissions, the states ... you can add everything you need.
If you include the authentication you can choose the name of the resource, the default user is used but you can replace it by any other name (eg Author) as long as you remember to specify it when you create the following resources to allow the generator successfully compile the file permissions. To do this you need to pass the parameter to the generator of the resource, for example:
rails g leosca category name --auth_class=Author

The generator leolay replaces the original file en.yml (initially empty) with his custom, answer y to overwrite it. It is not done automatically if it is not the first generation (eg to update the generator), in this case we have to manually manage the conflicts.

At this point the application is already running and we can verify this by entering the directory of the new application and starting the server:
rails s
http://localhost:3000/

You will be prompted to authenticate, insert:
abcd1234

And you will be redirected to the dashboard:

It has been already created the management of the users and this is the starting point for developing the application.. We provide resources thus creating two category:

In the REST architecture, a resource is largely attributable to a table on a database.

rails g leosca category name

Since Rails 3.2, the fields are considered as string if type is omitted so that is no longer necessary to specify it.

and now we can add the resource ticket:

rails g leosca ticket category:references title description:text state:integer

category:references tells to Rails to create an association with that resource: it creates a foreign key category_id and an index that uses to manage the relationship, in the ticket model there will be:

belongs_to :category

means that the ticket can query its category but not vice versa, if we want to query all the ticket you need to enter in the template category:

has_many :tickets

Let's go back to the project and check the result but first we have to apply to the db in that the generator has created for us:

rake db:migrate
==  CreateCategories: migrating ===============================================
-- create_table(:categories)
-> 0.1430s
==  CreateCategories: migrated (0.1440s) ======================================
==  CreateTickets: migrating ==================================================
-- create_table(:tickets)
-> 0.0040s
-> 0.0010s
==  CreateTickets: migrated (0.0070s) =========================================


in order to facilitate the development stage, are generated generic records that you may also update before insert in the db to create more real cases:

#db/seeds.rb
[
{ :id => 1, :name => "Bug" },
{ :id => 2, :name => "Update" },
{ :id => 3, :name => "Implementation" },
].each do |fields|
category = Category.new fields
category.id = fields[:id]
category.save
end

Ticket.create([
{  :category_id => 1,  :title => "New bug",  :description => "I had a bug, damn!",  :state => 10 },
{  :category_id => 2,  :title => "Change this section",  :description => "I require a change",  :state => 10 },
{  :category_id => 3,  :title => "New section",  :description => "I need a new resource to manage ...",  :state => 10 },
])


We want the id of the category is fixed and does not automatically attributed so we specify it and add it to the db with an alternative way to what is proposed by the generator. I do not know if there is a better way to do it.

Before proceeding we add the attribute category_id to the list of accessible attributes:
#app/models/ticket.rb

class Ticket < ActiveRecord::Base
belongs_to :category
attr_accessible :description, :state, :title, :category_id
end


And now we add these records to the database:
rake db:seed

If you receive the following error:
rake aborted!
Can't mass-assign protected attributes: category_id
You have not added category_id to the list of accessible attributes.

If you receive a "primary key violation" error:
rake aborted!
SQLite3::ConstraintException: PRIMARY KEY must be unique
You're probably running the import again, comments the categories in the file seeds.rb

You can run it multiple times to add more records.

The test application is ready, restart the server and update the browser:
rails s
http://localhost:3000/

Easy, not it?

The next steps are:
1. Developing localization
2. Customize permissions
4. Develop models
5. Create any alternative frontend

#### Localization

The application comes localized in English (default) and Italian (but you can extend the generator pretty easily) and just change the tags within files config/locales/*.yml

#### Customize permissions

Using cancan, edit the permissions is very simple, it is all contained within the file app/models/ability.rb

#### Customize views

Also Active Admin customizations are very simple. Everything is concentrated in the file relative to resource: list, consultation, form data, exports etc..
Each file is located in the folder app/admin/*.rb

We can customize many things:

ActiveAdmin.register Ticket do

#change the default sort
config.sort_order = 'id_asc'

#add scopes: lists with preset filters
scope :open
scope :closed

controller do
authorize_resource
end

#choose the column in the list
index do
id_column
column :category
column :title
column :description
column I18n.t('attributes.ticket.state'), :sortable => :state do |ticket|
span ticket.human_state_name.capitalize, :class => "status #{ticket.state_name}"
end
default_actions
end

#...in the show
show do |ticket|
attributes_table do
row :category
row :title
row :description
row I18n.t('attributes.ticket.state') do
span ticket.human_state_name.capitalize, :class => "status #{ticket.state_name}"
end
end
end

#...the form
form do |f|
f.inputs do
f.input :category
f.input :title
f.input :description
f.input :state, :as => :select, :collection => Ticket.state_machine.states.map{|s|[s.human_name.capitalize, s.value]}, :include_blank => false
end
f.buttons
end

#...and customize the export
csv do
column I18n.t('models.category') do |ticket|
ticket.category.try(:name)
end
column :title
column :description
column I18n.t('attributes.ticket.state') do |ticket|
ticket.human_state_name.capitalize
end
column(I18n.t('attributes.created_at')) { |user| user.created_at.strftime("%d/%m/%Y") }
column(I18n.t('attributes.updated_at')) { |user| user.updated_at.strftime("%d/%m/%Y") }
end
end

...and many other things for which I refer you to the official documentation of ActiveAdmin.

In rails is automatic but if it is not indicated to load them in advance, they will be retrieved when needed.

If we check in log / development.log will notice three individual queries to the archive of the categories, one for each ticket for which you show the name:


[1m [36mCategory Load (1.0ms) [0m   [1mSELECT "categories".* FROM "categories" WHERE "categories"."id" = 1 LIMIT 1 [0m
[1m [35mCategory Load (1.0ms) [0m  SELECT "categories".* FROM "categories" WHERE "categories"."id" = 2 LIMIT 1
[1m [36mCategory Load (1.0ms) [0m   [1mSELECT "categories".* FROM "categories" WHERE "categories"."id" = 3 LIMIT 1 [0m


For small lists is not a big problem but instead it is for large amounts of data, such as extractions csv format, so you need a little change on the controller. ActiveAdmin relies on Inherited Resources and you must act in this way:

ActiveAdmin.register Ticket do
#...[CUT]...
controller do
authorize_resource
def index
super do |format|
format.html { @tickets = @tickets.includes(:category) }
format.csv { @tickets = @tickets.includes(:category) }
end
end
end
#...[CUT]...
end


If you now check the log again you find a single query:
  [1m [36mCategory Load (0.0ms) [0m   [1mSELECT "categories".* FROM "categories" WHERE "categories"."id" IN (1, 2, 3) [0m

#### Develop models

Models management is also very simple. We modify the related files in app / models / *. Rb adding validations, scopes, state management, etc..

class Ticket < ActiveRecord::Base
belongs_to :category
attr_accessible :description, :state, :title, :category_id

state_machine :state, :initial => :new do
state :new,           :value => 10
state :working,       :value => 20
state :canceled,      :value => 30
state :completed,     :value => 40
end

OPEN_STATES =  [state_machine.states[:new].value,
state_machine.states[:working].value]
CLOSED_STATES =  [state_machine.states[:canceled].value,
state_machine.states[:completed].value]

validates :state, :inclusion => { :in => state_machine.states.map(&:value),
:message => "%{value} is not a valid value! Available states: #{state_machine.states.map(&:value).compact.join(', ')}" }, :allow_nil => true

scope :open, where(:state => OPEN_STATES)
scope :closed, where(:state => CLOSED_STATES)
end

And here is the customized version:

 Visualizzazione
 Form dati
 Lista

For the moment thats all

## Wednesday, 15 August 2012

### Active Leonardo

I created a new tool designed for developers like me who usually have to create web applications from scratch in few minutes. Often the work is thrown away but often continues and evolves into a concrete project that needs to take a more substantial appearance. This arrangement saves precious time and also defines the mold.

Before you continue reading you need to know rails and its foundations.

The name of this project is ActiveLeonardo, a handy gem to quickly set up an application with rails 3.2. The source are available on github .

As the name suggests, is a simplified variant of the previous customizations that implements less invasive generates only a skeleton and is based primarily on active admin gem.
I abbandoned the last project because it required a challenging maintenance and the result was, however, a solution for only administrative purpose.

It 's still divided into two generators:
1. leolay, that is performed once just after the creation of the application
2. leosca, that is run for the generation of each resource and replaces the rails scaffold

#### Leolay prepares the way for leosca

Prepare everything you need to get a working application. What does in the detail depends on what you includes:
• creates the user management and creates three test profiles
• creates localizations files
• generates a graphic style derived from activeadmin for any external sections

#### Generate resources with leosca

As the original scaffold, is a container of "things to do", some it makes directly but many others through the invocation of other generators. For each resource is finally invoked the generator activeadmin and on its result then it applies a slight customization for integration with the section of authorization managed once again with the cancan profiles.

#### How to use

The instructions are available at the project page where you will find a simple tutorial.

## Thursday, 23 February 2012

### Leonardo: update to 1.10 version

With 1.10 version I introduced the following changes:

• In the index page, I moved the filters on the right and layout now seems more clean. For numeric fields, and dates can be filtered more easily by inserting the operator <, >, <>, <= o >= directly in the text field.
• The generator detects the field named "state" and imposed a series of operations to manage the state (intended as the process status) in accordance with the gem state_machine.
• Still in the index page, clicking the arrow beside the name of the nested resource, will perform an ajax call that adds information dynamically under the parent resource. Clicking on the name instead, you run a http call as before.
• I improved the automatic routes creation

But we get into detail with some examples.
Create a new application and name it as suggested by your imagination, I call it Leonardo:

rails new Leonardo -m template.rb

At the moment is recommended to use the template locally, so download it or take it from the root where you installed the gem.

Respond y everything you want to include. You can choose whether to install the gems locally, by specifying the name of the folder, or if you install it in the default path by simply pressing Enter. I also added the choise to install activeadmin and if you decide to include it you need:

rename the file app\assets\stylesheets\application.css to application.css.scss

inside that file remove the line
*= require_tree .

@import "cloudy";
cloudy is the style name, currently also the only one

if we now start the server and visit the address
http://127.0.0.1:3000

You should see the graphic layout without defects created by the interference of the activeadmin css
and here

will be accessible only to the dashboard and I would refer you to the documentation for how to use it.
To sign in the leonardo interface instead, you have the usual three users with three different roles that can be managed as provided by the gem cancan:user@leonardo.com
manager@leonardo.com

replace leonardo with the name of your application
user@yourapp.com

for all these the password is è abcd1234

now create the product resource taking advantage of rails 3.2:

rails g leosca product name description:text 'price:decimal{9,2}' 'in_stock:integer{2}' available:boolean from:date 'state:integer{1}'

create the table
rake db:migrate

If we added the state field, Leonardo tries to involve the gem state_machine so you have to add the states into the model:

class Product < ActiveRecord::Base
state_machine :state, :initial => :new do
state :new,         :value => 10
state :working,     :value => 20
state :completed,   :value => 30
state :closed,      :value => 40
state :canceled,    :value => 50
end
end


before populate the new table, edit the file db \ seed.rb customizing state values ​​as included in the model after which we can perform:
rake db:seed

Visit the product list:

Note the filter on the price for values ​​above 10 pound, with the operator directly in the text box before the value

Note also the State column with the default color and description I18n both easily customizable.

To change the language, you just pass the parameter lang anywhere in the application:
http://127.0.0.1:4000/products?lang=it

will change the standard text and the names will be translated manually into the file:
\config\locales\it.yml

In edit view, the states can be update by a select box:

Now create comment, a nested resource under product:

rails g leosca comment product:references body:text approved:boolean 'score:integer{1}' --under=product

Also in this case, before to populate the table you can customize the file db \ seed.rb inserting for example more records associated with the first product. Furthermore I usually comment out the entries have already been used to avoid creating duplicates, then perform again:
rake db:seed

if we visit the previous list, you will find the reference to nested resources and if you click on the small arrow next to the name the list will be updated directly with the list of related resource:

Of course leonardo provides only a starting point and nothing more than an unconventional scaffolds

Unfortunately, I was not able to update rspec tests which do not pass in the presence of the state field, but will be in next version.

I hope that this work will come in handy. There is still much to do and anyone interested to help me out can send me an email.

## Tuesday, 13 December 2011

### Leonardo: update to version 1.9

I just released the1.9 version which enhances and completes the resources management.

If you use the --under option to nest the new resource under another existing one, must be edited the file config / routes.rb because the operation will create the new routes nested, overwriting the originals.

For example if we create the product resource, leonardo will create these routes:
resources :products do
post :select,           :on => :collection
post :edit_multiple,    :on => :collection
put  :update_multiple,  :on => :collection
put  :create_multiple,  :on => :collection
end


if then we create the comment resource under product you will get:
resources :products do
post :select,           :on => :collection
post :edit_multiple,    :on => :collection
put  :update_multiple,  :on => :collection
put  :create_multiple,  :on => :collection
end
end

resources :products do
post :select,           :on => :collection
post :edit_multiple,    :on => :collection
put  :update_multiple,  :on => :collection
put  :create_multiple,  :on => :collection
end


but you have to join it to get something like this:
resources :products do
post :select,           :on => :collection
post :edit_multiple,    :on => :collection
put  :update_multiple,  :on => :collection
put  :create_multiple,  :on => :collection
post :select,           :on => :collection
post :edit_multiple,    :on => :collection
put  :update_multiple,  :on => :collection
put  :create_multiple,  :on => :collection
end
end

Moreover, the list of resources shows a link to the nested resource for the parent who uses the name field. If not present you should replace it with some other field otherwise you can add the method name into the model:
class Product < ActiveRecord::Base

def name
self.title
end
end


## Monday, 10 October 2011

### Leonardo: Update to version 1.8

http://railscasts.com/episodes/228-sortable-table-columns

I also added by default the auto submit to the search form on the index view when the values ​​are changed for fields like select, radio ... those with a net change of the value, avoiding the text box to not encumbering the database. However it is possible to add or remove this feature, by adding or removing the autosubmit class :

<%= f.collection_select :category_id, Category.all, :id, :name, {:prompt => true}, {:class => 'autosubmit'} %>

In custom.js file (called from application.js) I added a bind (or more precisely, a live):

$('.autosubmit').live('change', function() { setTimeout("$('#"+this.id+"').parents('form:first').submit();", 300);
return false;
});


I use a timeout to run the submit after eventual updates, usually hidden fields coupled to self completions which currently leonardo does not handle but it will do soon.

With version 1.7 released in late September that I have introduced the option leospace:

rails g leosca decode name:string --leospace=admin

I fixed the code for compatibility with Ruby 1.9.2 which has a slightly different String class.

Now the development users are no longer created by migration, being a database population their place is in the file db / seeds.rb used with rake db: seed. Handy for db:reset or db: schema: load utilities that previously they deleted users.

Create the resource "decode " in no namespace and only the management under the namespace specified in the parameter leospace.

The original scaffold has something similar as well, let's take this example:
rails g scaffold admin/decode name:string

This creates the resource and its management in admin namespace.

We examine the differences:

Both will create paths in admin namespace:
ecc.

With the scaffold, the resource is called Admin:: Decode and table admin_decodes

With leonardo, the resource is called only Decode and it is not under a namespace. The table is called decodes.

The transaction meets the need to create different interfaces for the same resource. Of course you can also use the original leonardo Methodology:
rails g leosca admin/decode name:string

1.8.3 (November 8th, 2011) Marco Mastrodonato
• Controller/sort_column => Fixed an issue with multiple tables
• Dev users are now added by rake db:seed, no more by migration
1.8.2 (October 10th, 2011) Marco Mastrodonato
• List: Added id as first column
• Replaced String.any? with String.size>0 for ruby 1.9.2 support

1.8.1 (October 10th, 2011) Marco Mastrodonato
• Updated rspec to pass index view test with two new controller helpers
•  Date managed with datepicker are now in year-month-day format and now works with sqlite3
• Added autosubmit class by default. A new function in custom.js let you to autosubmit searches on filter fields change event
1.8.0 (October 7th, 2011) Marco Mastrodonato
1.7.2 (October 5th, 2011) Marco Mastrodonato
• Updated formtastic support to version 2.0
• Updated template.rb
1.7.1 (October 3th, 2011) Marco Mastrodonato
• Fixed a layout issue
1.7.0 (September 28th, 2011) Marco Mastrodonato
• New feature to add a resource management within a namescape. Unlike the original way (rails g leosca admin/resource ...which remains available), the resource is not under the namespace but only its management so you could create one for several kind of users. Try it adding the new option like this example: --leospace=admin
• Huge code improvements

## Tuesday, 20 September 2011

### Leonardo: a Rails 3.1 application generator

Update to 1.6 version

I created a new Rails application generator to create 3.1 and automate tasks that are repetitive.

The name of the gem is
leonardo and it consists of two generators:
1. leolay: to build the layout
2. leosca: to generate the resource (it replaces original scaffold)

## Why create a new generator if there is already the rails scaffold??

The scaffold generator is a handy tool which you can even customize with ease, but is designed for educational purposes and customization is limited to the views. In production I needed something more complete and customizable.

## Environment setup and gem installation

Unless we already have one, we create a new ruby environment with rails 3.1:
gem install rails

We can run:
gem install leonardo

...but it is not necessary and I recommend using the process I am about to describe:

create a new application using the template I have prepared, reccomended to facilitate the start-up and to better take advantage of the gem:

rails new NewApp -m http://dl.dropbox.com/u/52600966/template.rb

If the link does not work you can still find the template in the root of the gem

Leonardo relies on the following external gems:
cancan to manage permissions
warden/devise to handle authentication
formtastic for data management
kaminari for paging
rspec/capybara/factory girl/selenium for testing
... and others with whom there is not a close relationship but they are useful to handle other tasks.

The template will propose the adoption of the aforementioned gems, i raccomended to install all answering all "y" or pressing enter when a default is proposed (for example: devise proposes "user" as model name).

It will then run a bundle install to verify the presence of gems and then will perform the various generations, all will last about a minute.

The generation of the layout will ask for confirmation to replace the file en.yml, answer y. I prefer not to force the replacement to allow other executions of the generator leolay if you wanted to update the layout.

At the end you will get an application, "ready to go," allowing them to guide development on the application.

Let's move the application folder and we start the server:cd NewApp
rails s
point your browser at http://localhost:3000 to access the home

If you click on "Sign in" you will be prompted to authenticate (if you included it) for quick access, you can enter:

Creates three users with three different roles (if you have included permission):
2. manager@newapp.com
3. user@newapp.com

Of course it's users for purposes related to the development.

We can consult and modify roles access to the file app / models / ability.rb as expected from cancan.

To change the language is enough to send the new one as the value of the lang parameter, eg:http://localhost:3000/?lang=it

Currently it manages language :it and :en. Add support for another language is simple, just add the yml files in the folder where you will find the first two, of course, must have the same tags.

## Customize the layout

• First you replace the logo with your own.
• You can change the color editing app \ assets \ stylesheets \ stylename.sass (default cloudy). Choosing primary and secondary color, the shades are calculated by sass.
• You can customize the paging: Rails g kaminari: views THEME and replace the theme with your favorite theme. Currently available are github and google
• You can customize jquery-ui, currently uses a style similar to the lightness
• For larger customizations edit the HTML in the templates and layout of individual views. To do this copy the template in the project with Rails g leosca: install

## Generate resources

Now we generate some resources leosca using the generator, a sort of custom scaffold:

rails g leosca category name:string active:boolean

rails g leosca product category:references name:string description:text price:decimal released_at:date

To create a nested resource just add the --under=parent for example if we want the product to be nested under category:
rails g leosca product ... --under=category

A resource exists within the parent resource and paths are like this:
http://localhost:3000/categories/1/products

When Leonardo detects the presence of a relationship (such as references or belongs_to) is prepared everything necessary for connecting the resources and also whether the resource is nested:
• nested paths will be created in the controller, in the views and specs
• will be updated the list of parent resource with links to related resources
• the creation and / or modification does not require the selection of products related because the parent resource has already been selected before the consultation.

We then create two new tables to the database including:
rake db:migrate

and we also perform the data population that leosca has prepared for us:
rake db:seed

The image above shows the case where the product was not nested resource under the category.

Some notes:
• The export data in CSV currently does not work if you activate the paging ajax, I'm looking for a good way to solve.
• Into the lists are automatically entered all fields in order to apply the filter, then eliminate those that do not interest us. The filters do not work with sqlite 3 and boolean fields due to a bug in the driver that does not generate a correct sql. Works seamlessly with the SQLServer.
• Related objects show a link with the name. If the table does not have the field name, is used id which should be replaced with the field that more it represents.
• Only the paging, the show and destroy operation is managed through ajax.
• About the users automatically created: admin can do everything, manager all the CRUD operations, user cannot to delete.
• The field labels are auto inserted but the translation must do it by yourself into config/locales/*.yml

## Test

Leonardo creates everything you need for testing, even some additions to test the behavior of ajax sections:

rake spec

I use Firefox on Windows (I have not yet been able to do tests with linux) and I got all green, even in the presence of nested resources, though some combinations may not be covered.

Only A Few Recommendations: it will be opening a new session of firefox which you must set it to full screen otherwise selenium will do hard work to click on links. Sometimes instead, there are lag issues, in case of errors of this kind simply repeat the test.

## How to customize the generator

Simply install it in your project and customize it to suit your needs:
rails g leosca:install
is located under lib and any changes will take precedence on the gem

## Conclusions

For further information or updates on future developments, please consult the project homepage:
https://github.com/marcomd/Leonardo