When I used Rails for the first time I was impressed by the use of multiple environments to handle different setup, policies and behavior of an application. A few year ago use of environments wasn’t so common and switching between development, test and production was an innovation for me.

Anyway big projects who use custom frameworks introduced this structure several years before. I had the pleasure to work over a lot of legacy code who implement different environments setup. For example classified ADS channel of Repubblica.it (built by my mentor @FabiolousMate) uses dev, demo and production. Other projects I worked on use staging. After have listened a lot of opinions I asked myself which are the most important environments and if three are enough.

I’m mostly a Ruby developer and I know the Rails ecosystem who uses 3 basic environment.

  • development is used to when you code. Source code is reloaded each time. Log is EXTREMELY verbose. Libraries includes debug and error logging features. Database is full of garbage data.
  • test is for automatic testing. Data is loaded and cleaned automatically every time you run tests. Everything can be mocked (database, APIs, external services, …). Libraries includes testing frameworks and log is just for test output.
  • production is to be safe. Logging is just for errors. Sometimes there is a caching layer. Libraries are loaded once. Data is replicated. Everything is set up to improve both performances and robustness.

These environments are really useful in order to manage application development. Unfortunately are not enough to handle every situation. For example production is not appropriate for testing new feature because of the poor log and the strong optimization (and the precious production data) and is not appropriate as well for demo purpose because has to be used by customers. Development is alike not appropriate to find bottlenecks because of messy data and debug code.

In my experience I usually add three more environment to my application trying to fit every situation. Most of cases these are enough.

  • staging is for deep testing of new features. Production data and development logging and libraries. Enable you to test side effects of your new features in the real world. If an edit works here probably works also in production
  • demo is for showtime. Production environment with sandboxes features and demo data. You can open this environment to anyone and he can play whatever he wants without dangers.
  • profile is to find bottlenecks. Development environment with specific library to profile and fine tuning of you process. You can adjust data to stress your system without worry about coherence of data.

This is IMHO a good setup of you deploy environments. Depending on projects some of these aren’t useful but in a large project each one can save you life.

Serialized fields in Rails are a really useful feature to store structured data related to a single element of your application. Performance usually aren’t so stunning because they are stored in a text field.

Recently to overcome this limit hstore on PostgreSQL and similar structure on other DBMS have gained popularity.

Anyway editing data using a form still require a lot of code. Last week a was working on a form to edit options of an elements stored into serialized field and I found this question on StackOverflow. It seems a really interesting solution. For a serialized field called properties

class Element < ActiveRecord::Base
serialize :properties
end

I can dynamically define accessor method for any field I need.

class Element < ActiveRecord::Base
serialize :properties
def self.serialized_attr_accessor(*args)
args.each do |method_name|
eval "
def #{method_name}
(self.properties || {})[:#{method_name}]
end
def #{method_name}=(value)
self.properties ||= {}
self.properties[:#{method_name}] = value
end
attr_accessible :#{method_name}
"
end
end
serialized_attr_accessor :field1, :field2, :field3
end

And then you can easies access fields in a view

#haml
- form_for @element do |f|
= f.text_field :field1
= f.text_field :field2
= f.text_field :field3

IMHO it’s a really clean way to improve quality of accessor code.

Recently were released two important updates in the Ruby world (informally named ROR24):

  1. Ruby 2.0.0-p0
    http://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-is-released/
  2. Rails 4.0.beta1
    http://weblog.rubyonrails.org/2013/2/25/Rails-4-0-beta1/

Following this release, PragProg has released a new update for two of the most popular book about this topics.

Programming Ruby (the pickaxe book)
by Dave Thomas, with Chad Fowler and Andy Hunt

programming_ruby_2

Agile Web Development with Rails
by Sam Ruby, Dave Thomas and David Heinemeier Hansson

agile_web_devlopment_with_rails_4

I bought them yesterday. At first look, updates look cool also if there are only minor updates. In the coming days I’m going to practice about these new stuff and write some posts about it 😉

Recently I have to build a JSON API to wrap the connection to persistence layer in order to be able to change (or add) DBMS later and define more structured logic (authentication, selective caching, …). I didn’t know which DBMS to use but I had to start develop the other components which relay on this persistence layer.

To avoid delay while choosing DBMS setup we decided to build a prototype using Rails and MySQL in order to start defining API’s methods. Rails is really useful when you had to create a MVC application but includes too much stuff if you only need to build an API. This is why usually we use Sinatra.

This time we tried Rails::API,  a subset of a normal Rails application. It’s a bit faster and lightweight and you can use your existing Rails app.

To use it you only need to add gem to Gemfile:

gem 'rails-api'

change the ancestor of ApplicationController

class ApplicationController < ActionController::API
# [...]
end

and comment out the protect_from_forgery call if you are using it.

Everything seems to be ok. Created four models, a couple of controllers with usual REST action and everything is done: my prototype is up and running.

Unfortunately there are some new Rails feature that aren’t well supported by this gem. The most important is the wrap_parameters support IMHO. The ActionController::ParamsWrapper should automatically make a copy of request’s parameters into an hash named as the element you are sending.

For example, if you send to /users:

{"name": "Andrea"}

controller should receive:

{"name" => "Andrea", "user" => {"name" => "Andrea"}}

It is very convenient if you use standard ActiveRecord-based scaffold but Rails::API doesn’t support well this initializer: https://github.com/rails-api/rails-api/issues/33. You have to setup it manually.

Into each controller you must define how to wrap params:

class UsersController < ApplicationController
wrap_parameters :person, include: [:name], format: :json
# [...]
end

Is the only issue i found but took me a lot of time to be solved. I choose Rails because is easy and I can build a prototype in a flash but I think is still to early to use it to build an API, maybe Rails 4. At the moment I still prefer to use Sinatra.

Thanks to @olinicola, he built the prototype and found the solution to the issue.

ActiveRecord is an incredibly powerful tool but the Rails Guides doesn’t cover every possible situation and the ActiveRecord’s official documentation is huge. Find something you are looking for can be hard. If you have to do something strange and you have no time to search you have to hope someone had got the same problem and posted it on StackOverflow or on its own blog.

Recently I have to modelize a relation where a resource belongs to an entity and contemporary is related to N other entities.

The One-to-Many relation is easy: use belongs_to and has_many. The other part is harder because you need to use a connection table (HABTM doesn’t work) and you need to rename relation because its name is already taken.

You can use a connection table using through attribute:

has_many :connection_table
has_many :items, through: :connection_table

and rename a has_many through relation using source attribute:

has_many :related_items, through: :connection_table, source: :items

Problem solved:

class Resource < ActiveRecord::Base
belongs_to :entity
has_many :connections
has_many :related_entities,
through: :connections, source: :entity
end

 

class Entity < ActiveRecord::Base
has_many :resources
has_many :connections
has_many :related_resources,
through: :connections, source: :resource
end

 

class Connection < ActiveRecord::Base
belongs_to :entity
belongs_to :resource
end

Thanks to @olinicola for the advises 🙂