Create Beautiful Administration Interfaces with Active Admin

Every web developer knows that creating an administration interface for their projects is an incredibly tedious task. Luckily, there are tools that make this task considerably simpler. In this tutorial, I’ll show you how to use Active Admin, a recently launched administration framework for Ruby on Rails applications.

 

You can use Active Admin to add an administration interface to your current project, or you can even use it to create a complete web application from scratch – quickly and easily.

Today, we’ll be doing the latter, by creating a fairly simple project management system. It might sound like quite a bit of work, but Active Admin will do the bulk of the work for us!


Step 1 – Set up the Development Environment

I’m going to assume you have some previous Ruby on Rails knowledge, especially involving model validations, since the rest of the application interface is going to be taken care of by Active Admin. Apart from that, you should have a development environment for Ruby on Rails 3.1 already set up, including Ruby 1.9.2.

Refer to this article if you require assistance installing Ruby and Rails.

Create the application we’ll be working on, by running the following command in your Terminal:

rails new active_admin

Next, open your Gemfile and add the following lines:

gem 'activeadmin'
gem 'meta_search', '>= 1.1.0.pre'

The last gem is required for Active Admin to work with Rails 3.1, so don’t forget it. After that’s done, run thebundle install command to install the gems. Now, we need to finish installing Active Admin, by running the following command:

rails generate active_admin:install

This will generate all needed initializers and migrations for Active Admin to work. It will also create anAdminUser model for authentication, so run rake db:migrate to create all the needed database tables. Apart from that, you need to add one line to your config/environments/development.rb file, so sending emails works:

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

Once that’s done, run rails server and point your browser to localhost:3000/admin. You’ll be greeted with a nice login form. Just type “admin@example.com” as the email and “password” as the password, and hit “Login”. You should now see a nice administration interface.


Step 2 – Configuring our User Model

As you can see from the webpage you just generated, there’s not much you can do, yet. We’re going to need a way to edit our users, and we can do that using Active Admin. The framework uses what it calls “Resources”. Resources map models to administration panels. You need to generate them using a command in your terminal, so Active Admin can know their existence, so go ahead and run:

rails generate active_admin:resource AdminUser

The syntax for that command is simple: just write the database model’s name at the end. This will generate a file inside the app/admin folder, called admin_users.rb. Now, if you refresh your browser you’ll see a new link at the top bar, called “Admin Users”. Clicking that will take you to the Admin User administration panel. Now, it’ll probably look a little too cluttered, since by default, Active Admin shows all of the model’s columns, and considering that the framework uses Devise for authentication, you’ll see a bunch of columns that are not really necessary. This takes us to the first part of our customization: the index page.

Admin User

Customizing Active Admin resources is fairly easy (and fun if you ask me). Openapp/admin/admin_users.rb on your favorite text editor and make it look like this:

ActiveAdmin.register AdminUser do
  index do
    column :email
    column :current_sign_in_at
    column :last_sign_in_at
    column :sign_in_count
    default_actions
  end
end

Let’s review the code:

  • The first line is created by Active Admin, and, like it says, it registers a new resource. This created the menu link at the top bar and all of the default actions, like the table you just saw.
  • The index method allows us to customize the index view, which is the table that shows all rows.
  • Inside of the block you pass to the index method, you specify which columns you do want to appear on the table, ie. writing column :email will have Active Admin show that column on the view.
  • default_actions is a convenience method that creates one last column with links to the detail, edition and deletion of the row.

One final step for this view is to customize the form. If you click the “New Admin User” link on the top right, you’ll see that the form also contains all of the columns on the model, which is obviously not very useful. Since Active Admin uses Devise, we only need to enter an email address to create a user, and the rest should be taken care of by the authentication gem. To customize the forms that Active Admin displays, there’s a method, called (you guessed it) form:

ActiveAdmin.register AdminUser do
  index do
    # ...
  end

  form do |f|
    f.inputs "Admin Details" do
      f.input :email
    end
    f.buttons
  end
end

If the code looks familiar to you, you’ve probably used the Formtastic gem before. Let’s take a look at the code:

  • You specify the form’s view by calling the form method and passing it a block with an argument (f in this case).
  • f.inputs creates a fieldset. Word of advice: you have to add at least one fieldset. Fields outside of one will simply not appear on the view.
  • To create a field, you simply call f.input and pass a symbol with the name of the model’s column, in this case, “email”.
  • f.buttons creates the “Submit” and “Cancel” buttons.

You can further customize the forms using the DSL (Domain Specific Language) provided by Formtastic, so take a look at tutorials about this gem.

One last step for this form to work: since we’re not providing a password, Devise is not going to let us create the record, so we need to add some code to the AdminUser model:

after_create { |admin| admin.send_reset_password_instructions }

def password_required?
  new_record? ? false : super
end

The after_create callback makes sure Devise sends the user a link to create a new password, and thepassword_required? method will allow us to create a user without providing a password.

Go try it out. Create a user, and then check your email for a link, which should let you create a new password, and log you into the sytem.


Step 3 – Projects

We are going to create a simple Project Management system. Not anything too complicated though, just something that will let us manage projects and tasks for the project, and assign tasks to certain users. First thing, is to create a project model:

rails generate model Project title:string

Active Admin relies on Rails’ models for validation, and we don’t want projects with no title, so let’s add some validations to the generated model:

# rails
validates :title, :presence => true

Now, we need to generate an Active Admin resource, by running:

rails generate active_admin:resource Project

For now, that’s all we need for projects. After migrating your database, take a look at the interface that you just created. Creating a project with no title fails, which is what we expected. See how much you accomplished with just a few lines of code?


Step 4 – Tasks

Projects aren’t very useful without tasks right? Let’s add that:

rails generate model Task project_id:integer admin_user_id:integer title:string is_done:boolean due_date:date

This creates a task model that we can associate with projects and users. The idea is that a task is assigned to someone and belongs to a project. We need to set those relations and validations in the model:

class Task < ActiveRecord::Base
  belongs_to :project
  belongs_to :admin_user

  validates :title, :project_id, :admin_user_id, :presence => true
  validates :is_done, :inclusion => { :in => [true, false] }
end

Remember to add the relations to the Project and AdminUser models as well:

class AdminUser < ActiveRecord::Base
  has_many :tasks

  # ...
end
class Project < ActiveRecord::Base
  has_many :tasks

  # ...
end

Migrate the database, and register the task model with Active Admin:

rails generate active_admin:resource Task

Now go and take a look at the tasks panel in your browser. You just created a project management system! Good job.

 

Step 5 – Making It Even Better

The system we just created isn’t too sophisticated. Luckily, Active Admin is not just about creating a nice scaffolding system, it gives you far more power than that. Let’s start with the Projects section. We don’t really need the idcreated and updated columns there, and we certainly don’t need to be able to search using those columns. Let’s make that happen:

index do
  column :title do |project|
    link_to project.title, admin_project_path(project)
  end

  default_actions
end

# Filter only by title
filter :title

A few notes here:

  • When you specify columns, you can customize what is printed on every row. Simply pass a block with an argument to it, and return whatever you want in there. In this case, we are printing a link to the project’s detail page, which is easier than clicking the “View” link on the right.
  • The filters on the right are also customizable. Just add a call to filter for every column you want to be able to filter with.

The project’s detail page is a little boring don’t you think? We don’t need the date columns and the id here, and we could show a list of the tasks more directly. Customizing the detail page is accomplished by using the show method in the app/admin/projects.rb file:

show :title => :title do
  panel "Tasks" do
    table_for project.tasks do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

Let’s walk through the code:

  • show :title => :title specifies the title the page will have. The second :title specifies the model’s column that will be used.
  • By calling panel "Tasks" we create a panel with the given title. Within it, we create a custom table for the project’s tasks, using table_for.
  • We then specify each column and the content’s it should have for each row.
    • The “Status” column will contain “Done” or “Pending” whether the task is done or not.status_tag is a method that renders the word passed with a very nice style, and you can define the color by passing a second argument with either : ok:warning and :error for the colors green, orange and red respectively.
    • The “Title” column will contain a link to the task so we can edit it.
    • The “Assigned To” column just contains the email of the person responsible.
    • The “Due Date” will contain the date the task is due, or just a “-” if there’s no date set.

Step 6 – Some Tweaks for the Tasks

How about an easy way to filter tasks that are due this week? Or tasks that are late? That’s easy! Just use a scope. In the tasks.rb file, add this:

scope :all, :default => true
scope :due_this_week do |tasks|
  tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now)
end
scope :late do |tasks|
  tasks.where('due_date < ?', Time.now)
end
scope :mine do |tasks|
  tasks.where(:admin_user_id => current_admin_user.id)
end

Let’s review that code:

  • scope :all defines the default scope, showing all rows.
  • scope accepts a symbol for the name, and you can pass a block with an argument. Inside the block you can refine a search according to what you need. You can also define the scope inside the model and simply name it the same as in this file.
  • As you can see, you can access the current logged in user’s object using current_admin_user.
Tasks2

Check it out! Just above the table, you’ll see some links, which quickly show you how many tasks there are per scope, and lets you quickly filter the list. You should further customize the table and search filters, but I’ll leave that task to you.

We’re now going to tweak the task’s detail view a bit, since it looks rather cluttered:

show do
  panel "Task Details" do
    attributes_table_for task do
      row("Status") { status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      row("Title") { task.title }
      row("Project") { link_to task.project.title, admin_project_path(task.project) }
      row("Assigned To") { link_to task.admin_user.email, admin_admin_user_path(task.admin_user) }
      row("Due Date") { task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end

  active_admin_comments
end

This will show a table for the attributes of the model (hence the method’s name, attributes_table_for). You specify the model, in this case task, and in the block passed, you define the rows you want to show. It’s roughly the same we defined for the project’s detail page, only for the task. You may be asking yourself: What’s that “active_admin_comments” method call for? Well, Active Admin provides a simple commenting system for each model. I enabled it here because commenting on a task could be very useful to discuss functionality, or something similar. If you don’t call that method, comments will be hidden.

Tasks

There’s another thing I’d like to show when viewing a task’s detail, and that’s the rest of the assignee’s tasks for that project. That’s easily done using sidebars!

sidebar "Other Tasks For This User", :only => :show do
  table_for current_admin_user.tasks.where(:project_id => task.project) do |t|
    t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
    t.column("Title") { |task| link_to task.title, admin_task_path(task) }
  end
end

This creates a sidebar panel, titled “Other Tasks For This User”, which is shown only on the “show” page. It will show a table for the currentadminuser, and all tasks where the project is the same as the project being shown (you see, task here will refer to the task being shown, since it’s a detail page for one task). The rest is more or less the same as before: some columns with task details.


Step 7 – The Dashboard

You may have noticed, when you first launched your browser and logged into your app, that there was a “Dashboard” section. This is a fully customizable page where you can show nearly anything: tables, statistics, whatever. We’re just going to add the user’s task list as an example. Open up the dashboards.rbfile and revise it, like so:

ActiveAdmin::Dashboards.build do
  section "Your tasks for this week" do
    table_for current_admin_user.tasks.where('due_date > ? and due_date < ?', Time.now, 1.week.from_now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end

  section "Tasks that are late" do
    table_for current_admin_user.tasks.where('due_date < ?', Time.now) do |t|
      t.column("Status") { |task| status_tag (task.is_done ? "Done" : "Pending"), (task.is_done ? :ok : :error) }
      t.column("Title") { |task| link_to task.title, admin_task_path(task) }
      t.column("Assigned To") { |task| task.admin_user.email }
      t.column("Due Date") { |task| task.due_date? ? l(task.due_date, :format => :long) : '-' }
    end
  end
end

The code should be fairly familiar to you. It essentially creates two sections (using the section method and a title), with one table each, which displays current and late tasks, respectively.

Dashboard

Conclusion

We’ve created an extensive application in very few steps. You may be surprised to know that there are plenty more features that Active Admin has to offer, but it’s not possible to cover them all in just one tutorial, certainly. If you’re interested in learning more about this gem, visit activeadmin.info.

You also might like to check out my project, called active_invoices on GitHub, which is a complete invoicing application made entirely with Active Admin.

Source : http://net.tutsplus.com/tutorials/ruby/create-beautiful-administration-interfaces-with-active-admin/

 

 

Humorously informative Rails logging

I’ll just leave this here:

 

01 module ActiveSupport
02   # Format the buffered logger with timestamp/severity info.
03   class BufferedLogger
04     NUMBER_TO_NAME_MAP  = {0=>'meh'1=>'fyi'2=>'hmm'3=>'wtf'4=>'omg'5=>'???'}
05     NUMBER_TO_COLOR_MAP = {0=>'1;30',  1=>'0;36'2=>'0;33'3=>'1;33',  4=>'1;31',  5=>'0;37'}
06  
07     def add(severity, message = nil, progname = nil, &block)
08       return if @level > severity
09       sevstring = NUMBER_TO_NAME_MAP[severity]
10       color     = NUMBER_TO_COLOR_MAP[severity]
11  
12       message = (message || (block && block.call) || progname).to_s
13       message = "\033[0;37m#{Time.now.to_s(:db)}\033[0m [\033[#{color}m" + sprintf("%-3s","#{sevstring}") + "\033[0m] #{message.strip} (pid:#{$$})\n" unless message[-1] == ?\n
14       buffer << message
15       auto_flush
16       message
17     end
18   end
19 end

(To use, put this code in an initializer in config/initializers and restart. Provides highly-readable, timestamped, colorized logging for your rails app.)

Source : http://cbpowell.wordpress.com/2011/12/08/humorously-informative-rails-logging/

 

Get Ruby on Rails working on Ubuntu 11.10

A long time I have not been using Ruby On Rails. I have decided to give it a try again, so started by installing on Ubuntu 11.10 in VirtualBox. From what I remember – I have never happened before having issue with RoR working out of the box. Unfortunately this was not the case this time. Everything started with something really new to me:

Invalid gemspec in [/var/lib/gems/1.8/specifications/json-1.6.1.gemspec]: invalid date format in specification: "2011-09-18 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/tilt-1.3.3.gemspec]: invalid date format in specification: "2011-08-25 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/json-1.6.1.gemspec]: invalid date format in specification: "2011-09-18 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/tilt-1.3.3.gemspec]: invalid date format in specification: "2011-08-25 00:00:00.000000000Z"

At the beginning I have tried to solve it in several ways – by installing ruby from APT sources via

 

1 sudo apt-get install rails

or just by installing rails from gems:

 

1 sudo gem install rails

Both re-installation and methods did not worked.
So I have to dig deeper.
After a lot of searching in google I found a simple solution. Obviously gemspecs have some different date formats that don’t validate. So if you have such a message, just run the following command:

 

1 sudo sed -i 's/ 00:00:00.000000000Z//' /var/lib/gems/1.8/specifications/*

This will fix the message. As soon as you install some new gem and you have this message – just run the script again.

Next it came the problem with SQLIte3:

Building native extensions. This could take a while...
ERROR: Error installing sqlite3-ruby:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal'
or 'yum install sqlite3-devel' and check your shared library search path (the
location where your sqlite3 shared library is located).
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.

This is solved by installing the development package of SQLite Ruby:

 

1 sudo apt-get install libsqlite3-dev

And at the end it came the problem with missing ExecJS engine:


/var/lib/gems/1.8/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
from /var/lib/gems/1.8/gems/execjs-1.2.9/lib/execjs.rb:5
from /home/npenkov/Projects/MyMeetingMinutes/config/application.rb:5:in `require'
from /home/npenkov/Projects/MyMeetingMinutes/config/application.rb:5
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:52:in `require'
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:52
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:49:in `tap'
from /var/lib/gems/1.8/gems/railties-3.1.1/lib/rails/commands.rb:49
from script/rails:6:in `require'
from script/rails:6

This I solved by downloading JavaScript engine from the URL mentioned (in my case Google V8) and putting on require in config/boot.rb

 

1 sudo gem install execjs
2 sudo gem install therubyracer

And adjust your applicaiton’s config/boot.rb:

 

1 require 'rubygems'
2 require 'execjs'
3 require 'v8'
4  
5 # Set up gems listed in the Gemfile.
6 ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
7  
8 require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

After all these fixes, everything ran smooth.
I am sure there could be more elegant way to fix all these issues, so feel free to propose solutions.
Enjoy!

Source : http://npenkov.com/2011/11/08/get-ruby-on-rails-working-on-ubuntu-11-10/

 

ActiveModel: Make Any Ruby Object Feel Like ActiveRecord

Rails 2.3 has a ton of really nice functionality locked up in monolithic components. I’ve posted quite a bit about how we’ve opened up a lot of that functionality in ActionPack, making it easier to reuse the router, dispatcher, and individual parts of ActionController. ActiveModel is another way we’ve exposed useful functionality to you in Rails 3.

Before I Begin, The ActiveModel API

Before I begin, there are two major elements to ActiveModel. The first is the ActiveModel API, the interface that models must adhere to in order to gain compatibility with ActionPack’s helpers. I’ll be talking more about that soon, but for now, the important thing about the ActiveModel API is that your models can become ActiveModel compliant without using a single line of Rails code.

In order to help you ensure that your models are compliant, ActiveModel comes with a module called ActiveModel::Lint that you can include into your test cases to test compliance with the API:

class LintTest < ActiveModel::TestCase
  include ActiveModel::Lint::Tests
 
  class CompliantModel
    extend ActiveModel::Naming
 
    def to_model
      self
    end
 
    def valid?()      true end
    def new_record?() true end
    def destroyed?()  true end
 
    def errors
      obj = Object.new
      def obj.[](key)         [] end
      def obj.full_messages() [] end
      obj
    end
  end
 
  def setup
    @model = CompliantModel.new
  end
end

The ActiveModel::Lint::Tests provide a series of tests that are run against the @model, testing for compliance.

ActiveModel Modules

The second interesting part of ActiveModel is a series of modules provided by ActiveModel that you can use to implement common model functionality on your own Ruby objects. These modules were extracted from ActiveRecord, and are now included in ActiveRecord.

Because we’re dogfooding these modules, you can be assured that APIs you bring in to your models will remain consistent with ActiveRecord, and that they’ll continue to be maintained in future releases of Rails.

The ActiveModel comes with internationalization baked in, providing an avenue for much better community sharing around translating error messages and the like.

The Validations System

This was perhaps the most frustrating coupling in ActiveRecord, because it meant that people writing libraries for, say, CouchDB had to choose between painstakingly copying the API over, allowing inconsistencies to creep in, or just inventing a whole new API.

Validations have a few different elements.

First, declaring the validations themselves. You’ve seen the usage before in ActiveRecord:

class Person < ActiveRecord::Base
  validates_presence_of :first_name, :last_name
end

To do the same thing for a plain old Ruby object, simply do the following:

class Person
  include ActiveModel::Validations
 
  validates_presence_of :first_name, :last_name
 
  attr_accessor :first_name, :last_name
  def initialize(first_name, last_name)
    @first_name, @last_name = first_name, last_name
  end
end

The validations system calls read_attribute_for_validation to get the attribute, but by default, it aliases that method to send, which supports the standard Ruby attribute system ofattr_accessor.

To use a more custom attribute lookup, you can do:

class Person
  include ActiveModel::Validations
 
  validates_presence_of :first_name, :last_name
 
  def initialize(attributes = {})
    @attributes = attributes
  end
 
  def read_attribute_for_validation(key)
    @attributes[key]
  end
end

Let’s look at what a validator actually is. First of all, the validates_presence_of method:

def validates_presence_of(*attr_names)
  validates_with PresenceValidator, _merge_attributes(attr_names)
end

You can see that validates_presence_of is using the more primitive validates_with, passing it the validator class, merging in {:attributes => attribute_names} into the options passed to the validator. Next, the validator itself:

class PresenceValidator < EachValidator
  def validate(record)
    record.errors.add_on_blank(attributes, options[:message])
  end
end

The EachValidator that it inherits from validates each attribute with the validate method. In this case, it adds the error message to the record, only if the attribute is blank.

The add_on_blank method does add(attribute, :blank, :default => custom_message) if value.blank? (among other things), which is adding the localized:blank message to the object. If you take a look at the built-in locale/en.yml looks like:

en:
  errors:
    # The default format use in full error messages.
    format: "{{attribute}} {{message}}"
 
    # The values :model, :attribute and :value are always available for interpolation
    # The value :count is available when applicable. Can be used for pluralization.
    messages:
      inclusion: "is not included in the list"
      exclusion: "is reserved"
      invalid: "is invalid"
      confirmation: "doesn't match confirmation"
      accepted: "must be accepted"
      empty: "can't be empty"
      blank: "can't be blank"
      too_long: "is too long (maximum is {{count}} characters)"
      too_short: "is too short (minimum is {{count}} characters)"
      wrong_length: "is the wrong length (should be {{count}} characters)"
      not_a_number: "is not a number"
      greater_than: "must be greater than {{count}}"
      greater_than_or_equal_to: "must be greater than or equal to {{count}}"
      equal_to: "must be equal to {{count}}"
      less_than: "must be less than {{count}}"
      less_than_or_equal_to: "must be less than or equal to {{count}}"
      odd: "must be odd"
      even: "must be even"

As a result, the error message will read first_name can't be blank.

The Error object is also a part of ActiveModel.

Serialization

ActiveRecord also comes with default serialization for JSON and XML, allowing you to do things like: @person.to_json(:except => :comment).

The main important part of the serialization support is adding general support for specifying the attributes to include across all serializers. That means that you can do@person.to_xml(:except => :comment) as well.

To add serialization support to your own model, you will need to include the serialization module and implement attributes. Check it out:

class Person
  include ActiveModel::Serialization
 
  attr_accessor :attributes
  def initialize(attributes)
    @attributes = attributes
  end
end
 
p = Person.new(:first_name => "Yukihiro", :last_name => "Matsumoto")
p.to_json #=> %|{"first_name": "Yukihiro", "last_name": "Matsumoto"}|
p.to_json(:only => :first_name) #=> %|{"first_name": "Yukihiro"}|

You can also pass in a :methods option to specify methods to call for certain attributes that are determined dynamically.

Here's the Person model with validations and serialization:

class Person
  include ActiveModel::Validations
  include ActiveModel::Serialization
 
  validates_presence_of :first_name, :last_name
 
  attr_accessor :attributes
  def initialize(attributes = {})
    @attributes = attributes
  end
 
  def read_attribute_for_validation(key)
    @attributes[key]
  end
end

Others

Those are just two of the modules available in ActiveModel. Some others include:

  • AttributeMethods: Makes it easy to add attributes that are set like table_name :foo
  • Callbacks: ActiveRecord-style lifecycle callbacks.
  • Dirty: Support for dirty tracking
  • Naming: Default implementations of model.model_name, which are used by ActionPack (for instance, when you do render :partial => model
  • Observing: ActiveRecord-style observers
  • StateMachine: A simple state-machine implementation for models
  • Translation: The core translation support

This mostly reflects the first step of ActiveRecord extractions done by Josh Peek for his Google Summer of Code project last summer. Over time, I expect to see more extractions from ActiveRecord and more abstractions built up around ActiveModel.

I also expect to see a community building up around things like adding new validators, translations, serializers and more, especially now that they can be reused not only in ActiveRecord, but in MongoMapper, Cassandra Object, and other ORMs that leverage ActiveModel's built-in modules.

Source : http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/

 

What’s so special about Ruby on Rails?

There are many reasons why Rails is special, but in order to keep things fairly short (and n00b friendly) I won’t delve too deeply into the mechanics. Instead I’ll cover the things that first drew me to the framework… and subsequently got me hooked!

The best technologies

One of the biggest draws to Rails is that it saves you a heap of trouble having to spend weeks or months researching/agonising over which technologies to adopt or methodologies to follow. If you’ve ever wanted someone to just tell you what the best are, then consider yourself told!

Here’s a list of some of them:

 

  • MVC – Model View Controller architecture
  • Convention over Configuration – design paradigm; spend less time configuring things!
  • DRY – Don’t Repeat Yourself
  • TDD – Test Driven Development
  • jQuery – Javascript library
  • SASS – Better CSS (variables &∓ conditionals!)
  • CoffeeScript – Nicer/easier to read/write Javascript
  • REST – REpresentational State Transfer – architecture for (stateless) networked applications

Ok, so it’s all opinion – but does it really matter so long as they are some of (if not the) best? If they’re good enough for a large number of talented devs then they’re good enough for me! I’m more than happy to bow to their superior knowledge (and if you’re smart, so should you).

It’s widely accepted that most of the default technologies, and the way Rails is set-up or goes about things is nothing short of awesomeness (it’s not called the best web framework for nothing you know!) and where you might feel the defaults are not to your taste, it’s easy to swap and change. Want to use jQuery? Fine. Want to use Prototype? That’s cool too. Prefer RSpec? No problem!

Ruby

Another big draw is the underlying language. Ruby is beautiful, powerful, elegant – and doesn’t get in your way. In fact, it’s not uncommon for people to say Ruby devs are happy devs, and they really are! The syntax is clear, constructs make sense and it all just flows naturally, making it a lovely language to work with. But make no mistake, the simple exterior harbours a very powerful interior. One that allows Ruby programmers to do things that programmers of many other languages can only dream of. Such as metaprogramming.

Another common saying is that while many come to Ruby because of Rails, they stay because of Ruby – and I couldn’t agree more. Rails wouldn’t be possible in another language, you’d get something similar, but it wouldn’t be the same – you’d be left feeling something wasn’t quite right, or that it’s almost there. Ruby is a key reason why Rails is so awe-inspiring and why so much of what it does is possible. Ruby is an all-purpose language too, so it’s not just for web apps (like say PHP).

Its creator Yukihiro “Matz” Matsumoto, has said that he is “trying to make Ruby natural, not simple” in a way that mirrors life. And many would argue he’s done just that – and then some.

Ruby is a language that inspires you, excites you – but don’t take my word for it, take it for a spin and see for yourself why it’s so hawt!

The community

The Ruby community rocks. You get the feeling everyone is on the same wavelength, most Rails devs seem to use OS X and TextMate for example (even down to the same ‘theme’!) but the conventions run a lot deeper. Whether it’s indentation style or using parentheses in your method definitions or calls (they’re optional in Ruby) there’s a ‘Ruby way’ and most in the community stick to it. It’s not because Ruby users are mindless zombies mind you, it’s because we genuinely like the same things and have similarly high standards.

The most important thing however, is how passionate and helpful the community is. Good enough just isn’t good enough. That’s why test driven development (TDD) is such a big thing in the Ruby community, and why you can rest assured that your peers will always help you remain on top of your game.

As you might expect, with something so cherished at its heart the community are eager to help each other get the best out of it. Testament to this are all the resources that are not only free, but have clearly taken a lot of time and effort to put together. Here’s a quick list:tryruby.org – where you get to try (and learn) Ruby in your browser, the extremely enjoyableRails for Zombies where the Envy Labs team take you through some gory screencasts then test your knowledge via the brain browser, the fantastic Railscasts which is nearly as old as Rails itself (!) and Rails Tutorial which is an excellent step-by-step that helps you build a twitter clone. There’s also the IRC #rubyonrails channel (irc.freenode.net) where there’s always some cheery soul willing to lend a helping hand, and the utterly brilliant Ruby Mendicant University (and Ruby Best Practises from the same person, Gregory Brown). Finally I just have to include Rails Hotline where if you get stuck and fancy talking to someone who might be able to help, you can – for free!

Pretty awesome don’t you think? And did I mention they are all free!?

If all of that isn’t enough for you (it should be, but if it isn’t…) then there’s one last thing that I find quite remarkable. I’m fairly new to Ruby, yet many leading or well known figures in the community have taken time out to speak to me. Yehuda Katz talked to me at length about learning Rails. Gregg Pollack was happy to discuss my ideas of where Rails for Zombies could lead. Ryan Bigg made the effort to get a .mobi version of his book (Rails 3 in Action) to me as he was keen on hearing my thoughts, and even DHH (the creator of Rails) has discussed totally unrelated topics via Twitter. And that’s just the people who I know are leading figures! I’ve also exchanged tweets with a number of others but won’t include them here for brevity – well apart from Russ Olsen, the author of two of my favourite Ruby books (Design Patterns in Ruby and Eloquent Ruby) who is following me on Twitter. *Faints

It’s fantastic that a large number of people high up in the community are willing to take time out for the nubes. Is there any wonder why the community is as cool as it is?

What Rails can do for you

This is probably what most of you are wondering – so what can Rails do that an off-the-shelf app (like say a forum platform such as vBulletin) can’t? Pretty much everything!

Tired of being restricted to a forum or blog as the core of your community site? Want to create something completely different with control over the finest detail? Then you’ve out-grown such software and a custom solution is what you really need.

If you want to build a custom site, free from the constraints of a predefined app, then using a framework like Rails is your best option. You could just skip the framework, and code everything from scratch – but why bother when so much of the hard work has already been done for you? Most of the fiddly ‘boring’ stuff is all set ready to go – you can just concentrate on the exciting stuff! And more importantly, if you’re not an expert already, Rails will teach you best practises that might otherwise take a lifetime to learn.

Additionally, and something that will interest you as you progress as a Rubyist, is that Rails allows you to use many of its components for your own non-Rails apps. Such as Active Record (the Object Relational Mapper) Active Support (Rails libraries) and even Action View (view helpers). Some of these even extend core Ruby classes such as Array, String and Hash – which is impossible in most other languages!

What will I need to learn?

Thankfully Rails teaches you a great deal about good web development, so you get to pick that up along the way – this in itself is pretty priceless. You will need to learn Ruby and Rails, though (and I assume you already have a working knowledge of HTML and CSS). You could get by with a little Ruby, as Rails does simplify many things – but learning Ruby is the only way to become a Rails Ninja, because Rails is Ruby, underneath it all.

If I’ve wet your appetite and you’re eager to learn but don’t know where to start or how to go about it, keep an eye out for a future blog post (Edit: the future is now! Link added…) where I will be doing a ‘Best way to learn Ruby & Rails‘ feature. In the meantime, here’s some quick tips:

  • If you’re new to programming go through Learn to Program by Chris Pine – a lovely introduction to OOP and Ruby.
  • Then do the excellent Kevin Skoglund, Ruby, and Ruby on Rails 3 courses over atLynda.com – they are in perfect 5 to 10 minute clips and Kevin really knows his stuff… and knows how to get you to know it!
  • After that check out David A. Black’s The Well Grounded Rubyist – one of the best Ruby books I have read to date. David is a real-life teacher, and it shows. He takes nothing for granted and walks you through every bit of code in the book so you never feel like giving up. This book really is a gem and I’m sure you’ll love it every bit as much as I do.

There’s more of course, but that’s enough to get you started. If you already know HTML and a bit of CSS, you’re ready to jump right in. So dive in and unleash your creations onto the world – faster, better, and while enjoying, yes enjoying, yourself along the way too.

Source : http://astonj.com/tech/whats-so-special-about-ruby-on-rails/

 

What’s special about Ruby?

Well let’s start with a few stand-out thoughts on Ruby:

  • Ruby is an object of beauty –> inspired & passionate developers
  • It’s elegant and concise –> a joy to work with
  • Easy to learn but very powerful –> more experienced developers
  • Is designed for programmer happiness –> all of the above

 
Before I go further, I should warn you that these are just my personal thoughts. I’m no programming guru (and relatively new to Ruby.) But, like countless others, I’ve fallen head-over-heels in lurrve with it and am extremely passionate about it (can you tell?)

Why Ruby?

So why would someone choose Ruby over any other language? Well I can’t speak for everyone else, but I can tell you why I turned to it.

In a nutshell, it felt like the closest thing we have to how a language should be written. In other words, it’s the best programming language out there. Let me rephrase that again. Ruby is the only language I came across that ticked most if not all the boxes for my requirements: it’s powerful, easy to learn, has a huge set of libraries, a vibrant community, the best web framework, and (as an unexpected bonus) is a genuine pleasure to use. Ruby was designed specifically with Programmer Happiness™ in mind. If you don’t believe me, ask its creator, Matz.

Why not Python/PHP/Java/[insert other language here]?

I think it’s important to quickly mention two of the main reasons why I think other languages fall short:

  • They are a pita to use (semicolons after every line/poor object models/ill-thought method names/using camelCaseForVariables, etc)
  • Or they just don’t have the same appeal – that something special – that Ruby does.
  • (or both)

I found Ruby because other languages either drove me away through their idiosyncrasies, convoluted or awkward ways, or because they just didn’t posses the special qualities that makes Ruby stand out. Qualities such as the best web framework (Ruby on Rails), a huge set of libraries, a vibrant community, etc. (As detailed above in ‘Why Ruby?’)

I wasn’t going to talk about other languages too much, but a few people have asked for code comparisons, so here they are. (Python code provided by @excid3, PHP code by @citalan.)

PHP

class Ball
{
    private $_colour;

        public function __construct($colour)
    {
        $this->_colour = $colour;
    }

        public function is_red()
    {
        return ($this->_colour == 'red' ? true : false);       
    }
}

$the_ball = new Ball('green');
echo ($the_ball->is_red() ? '' : 'The ball is not red');

Python

class Ball:
    def __init__(self, colour):
        self.colour = colour

            def is_red(self):
        return self.colour == "red"

        the_ball = Ball("green")

if not the_ball.is_red():
    print "The ball is not red"

Ruby

class Ball
  def initialize(colour)
    @colour = colour    
  end

    def is_red?
    @colour == "red"
  end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

Notice how clear and concise the Ruby code is? At a glance you quickly see what’s going on – the do ends provide excellent visual boundaries. Not too bare (like Python) but not convoluted like PHPs endless semicolons and brackets either. It strikes the perfect balance. If you really wanted to, you could even write the same code like this:

class Ball
  def initialize(colour); @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new("green")
puts "The ball is not red" unless the_ball.is_red?

or even like this – without parentheses:

class Ball
  def initialize colour; @colour = colour; end
  def is_red?; @colour == "red"; end
end

the_ball = Ball.new "green"
puts "The ball is not red" unless the_ball.is_red?

Most people stick with the original tho – perhaps without parentheses when it’s more appropriate (such as when using Rails or DSLs).

So what is special about Ruby?

Oh boy, where do I start? It’s clean, uncluttered and has an air of grace and elegance. No trailing semicolons. No need for parentheses for method calls (or definitions) …even hashes don’t need them if they’re the last argument in a call. Ruby is just so refreshing.

Once you get past how gorgeous Ruby code looks, you begin to read it. Ruby’s syntax is clear and concise, and there’s nearly always more than one way of doing something. These nuances matter because they give the language a natural feel – when you read Ruby, it reads better, moreso than what you might be used to in other languages.

Ok so maybe you think all that’s superficial (for the record… it’s not!) but either way – there’s a lot more going on under the hood.

Ruby is a ‘proper’ object orientated language. In fact, almost everything in Ruby is an object. Even classes (being an instance of the class Class.) Each object belongs to the class it was instantiated from, and… it even has it’s very own class, an Eigenclass (sometimes called the Singleton class). This is cool because it means individual objects, can truly be, er, individual! (You can give objects methods that other objects of the same class don’t have.)

You can ‘mix-in’ modules into your classes. Modules are like classes (actually, classes are descended from modules) with the main difference being that you can’t instantiate an object directly from them. A class can include as many modules as you want it to, so they are a great way to organise your code and share functionality between classes. They’re also handy for namespacing (so your class names are less likely to clash with someone else’s).

Ruby also gives us open classes, where you can reopen a class at any point and just add to it. You can even do this to standard classes, such as the String class – how many languages let you do that huh!? You could actually go on to modify existing code. Don’t like how a method works? No problem, change it! This is often referred to as monkey patching – something that often scares people from other languages. But that’s Ruby – it treats you as a grown-up, and lets you decide how responsible (or ruthless!) you want to be.

Ruby also gives us code blocks which are great for (amongst other things – such as DSL’s) closures – although we also get bindings for that. Duck typing means we don’t have to declare types beforehand and syntactic sugar lets us create setter methods like this:

def name=(x)
 name = x
end

Where ‘name=’ is the name of the method. Remember that parentheses are optional in Ruby? Well that, and the fact that Ruby lets us use an equals sign in our methods (as shown above) allows us to go on and do this:

name = "AstonJ"

It ignores the space between the equals sign and the rest of the method. Pretty cool, no? And that’s just scratching the surface – there’s loads more on offer!

Ruby also gives us powerful tools and tricks like introspection, dynamic methods, ghost methods, mimic methods, class macros and the creation of classes, methods and other code on-the-fly – something you might have heard of as metaprogramming: code that writes code. We also get proc objects (in a number of flavours) and all the usual stuff you’d expect, such as Arrays, Strings, Hashes, and a lot of others you might not, like method missing, class eval, bang methods and more! And that’s just the language itself!

The community

Here I’ll just copy and paste what I wrote in a previous post (What’s special about Ruby on Rails) as pretty much the same applies here.

The Ruby community rocks. You get the feeling everyone is on the same wavelength, most Rails devs seem to use OS X and TextMate for example (even down to the same ‘theme’!) but the conventions run a lot deeper. Whether it’s indentation style or using parentheses in your method definitions or calls (they’re optional in Ruby) there’s a ‘Ruby way’ and most in the community stick to it. It’s not because Ruby users are mindless zombies mind you, it’s because we genuinely like the same things and have similarly high standards.

The most important thing however, is how passionate and helpful the community is. Good enough just isn’t good enough. That’s why test driven development (TDD) is such a big thing in the Ruby community, and why you can rest assured that your peers will always help you stay on top of your game.

As you might expect, with something so cherished at its heart, the community are eager to help each other get the best out of it. Testament to this are all the resources that are not only free but have clearly taken a lot of time and effort to put together. Here’s a quick list:

  • tryruby.org – where you get to try (and learn) Ruby in your browser
  • the extremely enjoyable Rails for Zombies where the Envy Labs team take you through some gory screencasts then test your knowledge via the brain browser
  • the fantastic Railscasts which is nearly as old as Rails itself (!)
  • Rails Tutorial which is an excellent step-by-step that helps you build a twitter clone.
  • the IRC #rubyonrails channel (irc.freenode.net) where there’s always some cheery soul willing to lend a helping hand
  • the utterly brilliant Ruby Mendicant University (and Ruby Best Practices from the same person, Gregory Brown).
  • Finally I just have to include Rails Hotline where if you get stuck and fancy talking to someone who might be able to help, you can – for free!

Pretty awesome don’t you think? And did I mention they are all free!?

If all of that isn’t enough for you (it should be, but if it isn’t…) then there’s one last thing that I find quite remarkable. I’m fairly new to Ruby, yet many leading or well known figures in the community have taken time out to speak to me. Yehuda Katz talked to me at length about learning Rails. Gregg Pollack was happy to discuss my ideas of where Rails for Zombies could lead. Ryan Bigg made the effort to get a .mobi version of his book (Rails 3 in Action) to me as he was keen on hearing my thoughts, and even DHH (the creator of Rails) has discussed totally unrelated topics via Twitter. And that’s just the people who I know of who are leading figures! I’ve also exchanged tweets with a number of others but won’t include them here for brevity – well apart from Russ Olsen, the author of two of my favourite Ruby books (Design Patterns in Ruby and Eloquent Ruby) who is following me on Twitter. *Faints

It’s fantastic that a large number of people high up in the community are willing to take time out for the nubes. Is there any wonder why the community is as cool as it is?

I’d quickly like to add that the community isn’t just about programmers – many Ruby related businesses are very much part of it too. Companies like Engine Yard, Heroku, 37 signals, Shopify, Envy labs, Thoughtbot, Resolve Digital and countless others who give so much back. Just recently for example, Heroku have taken on Matz (the creator of Ruby) to work on Ruby full time – how brilliant is that!?

Culture

I want to cover culture on its own, because not all of it comes from the community. Of course the Ruby community will push you towards test driven development, writing good clean idiomatic code, contributing back to Ruby or other open source projects and generally helping you become a good Ruby citizen. But some cultural aspects are inherently down to the language itself – bizarre as that might sound.

The most important, and perhaps what will (and should?) make for interesting reading for managers and the ‘enterprise’, is the culture of learning.

If you go back to my list at the start of this post, you’ll see the brief list of things that make for Ruby Programmer Happiness™ – and what do people excel at? Things they enjoy :-)

I noticed a massive difference in my desire to learn Ruby, compared to PHP. PHP totally uninspired me. Don’t get me wrong, I was as desperate to learn to program as much as I’ve ever been (maybe even moreso back then) but all I wanted to do was get through the PHP books as quickly as possible just to ‘get on with it’. I never really enjoyed PHP, therefore I didn’t enjoy learning it – and that’s a problem, because people will generally only do the minimum or just skim over stuff, never truly understanding things.

Ruby, by contrast, is something I love. I enjoy reading about it and learning as much as I can. My appetite for all things Ruby is insatiable – and I’m not exactly a geek! It is just constantly, pleasantly, surprising me, and things just seem to ‘stick’ more (that’s testament to Matz wanting to make it a ‘natural’ language) so morale is always high. Additionally, because Ruby is very natural and therefore easy to pick up, you get people from all walks of life giving it a go – and that’s brilliant because it brings in creative people that might have otherwise not got into programming at all.

This, I think, is why you get better Ruby programmers. Of a higher skill-set and with more ‘experience’ – we tend to enjoy furthering our knowledge because we enjoy the topic so much. I really can’t stress this point enough, this is the reason (which itself is only there because of all the other factors) why I believe Ruby is going to grow at a phenomenal rate – it’s because we want to, not because we have to (JS/browsers) or we’re told we should do (Java/enterprise).

Everything else

There’s so much more to cover that it would be impossible to cover everything, so I’ll try to keep this brief. Ruby on Rails is widely considered to be the best web framework (see: What’s Special about Ruby on Rails? for more info) – it’s actually what first drew me to Ruby, and like many people, “I came for Rails but stayed for Ruby”! That’s not the only web framework btw, we also have Sinatra and a heap of others too (and also plenty of CMS and blog systems).

There has been over 281 million downloads of around 28 thousand RubyGems (aka libraries). From testing frameworks to web frameworks to authentication systems to backup systems to geocoding tools to e-commerce to email processing – chances are if you’re trying to do something there’s a gem out there that does it!

We also have lots of great learning material – what good is all that power if you’re just not able to learn it effectively? And lots of companies (like Engine Yard) offer sponsorships for training courses (or there’s even the Ruby University which I mentioned earlier).

Hopefully you’re beginning to get an idea why Ruby is special (and there’s a lot I haven’t even covered – such as the various Ruby implementations, like Jruby, Rubinious, MacRuby). Along with the beauty of language itself, we have all these other things – and they all add up to make Ruby the first class package that it is.

Conclusion

A programming language that inspires people is rather special – and Ruby is one that truly does just that. Add in its power, simplicity and elegance and you have a compelling package. One that will help you in work and play – and often blur the line between the two. Wouldn’t you want to get paid to do something you enjoy? I’m not kidding when I say that’s exactly how it is for almost all Rubyists I know – yet another reason why Ruby is special, for you, your boss, your client, and maybe even the world. (Well maybe!)

Where next?

So have I convinced you? If so keep an eye out for an upcoming post (Edit: link added…) where I’ll detail the best way to learn Ruby (& Rails) - but until then, be sure to check out the following

  • If you’re new to programming, I urge you to go through Learn to Program by Chris Pine – it’s a lovely introduction to OOP and Ruby.
  • If you have some programming experience, then do the excellent Kevin Skoglund Ruby course over at Lynda.com – they are in perfect 5 to 10 minute clips and Kevin really knows his stuff… and knows how to get you to know it!
  • After that, check out David A. Black’s The Well Grounded Rubyist – one of my all-time favourite Ruby books. David is a real-life teacher, and it shows. He takes nothing for granted and walks you through every bit of code in the book so you never feel like giving up.
  • And after that, get Russ Olsen’s Eloquent Ruby – another firm favourite. Russ is a very experienced programmer of a number of different langauges and he really helps you understand the ‘Ruby way’. When I read this book, I used the highlight function on my Kindle so much that in the end I thought ‘forget that – I might as well re-read the book later’ because I am pretty much highlighting it all anyway!

Don’t forget, keep an eye out for my How to Learn Ruby & Rails post – doing everything I list there will help you become fairly proficient in next to no time.

Good luck – and I hope to welcome you into the Ruby community soon!

Source : http://astonj.com/tech/whats-special-about-ruby/

 

LineCache - A module to read and cache file information of a Ruby program

== SYNOPSIS

The LineCache module allows one to get any line from any file, caching
the lines and file information on first access to the file. Although
the file may be any file, the common use is when the file is a Ruby
script since parsing of the file is done to figure out where the
statement boundaries are.

The routines here may be is useful when a small random sets of lines
are read from a single file, in particular in a debugger to show
source lines.

== Summary

  require 'linecache'
  lines = LineCache::getlines('/tmp/myruby.rb')
  # The following lines have same effect as the above.
  $: << '/tmp'
  Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb')

  line = LineCache::getline('/tmp/myruby.rb', 6)
  # Note lines[6] == line (if /tmp/myruby.rb has 6 lines)

  LineCache::clear_file_cache
  LineCache::clear_file_cache('/tmp/myruby.rb')
  LineCache::update_cache   # Check for modifications of all cached files.

== Credits

  This is a port of the module of the same name from the Python distribution.

  The idea for how TraceLineNumbers works, and some code was taken
  from ParseTree by Ryan Davis.

== Other stuff

Author::   Rocky Bernstein <rockyb@rubyforge.net>
License::  Copyright (c) 2007, 2008 Rocky Bernstein
           Released under the GNU GPL 2 license

== Warranty

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

$Id$Source : https://github.com/mark-moseley/linecache

Creating More Using Less Effort with Ruby on Rails

 

Creating More Using Less Effort with Ruby on Rails

If you build websites, you have no doubt heard about Ruby on Rails (RoR). But if you’re a designer or front-end developer or you’re using PHP without any application framework, it may seem like a big leap to adopt the Ruby on Rails approach. In this article, I hope to demystify Ruby on Rails and convince you that you can make the leap—and that it is a leap worth making if your needs fit within the Ruby on Rails “sweet spot” detailed below.

It does take time to learn new ways to do all the things you already know how to do, and to learn some new concepts and techniques at the same time. In the short term, switching technologies, even to Ruby on Rails, will destroy your productivity. Nevertheless, I’m convinced that many web developers would be more productive, produce better sites, and even have more fun if they took the leap and began using Ruby on Rails.

Fun for the whole family

Ruby on Rails (Rails for short) is a “full-stack” framework, which means that it covers both front-end and back-end design. This makes it an exceptionally potent tool in the hands of a “jack-of-all-trades” developer. Even if you’re primarily a front-end or a back-end developer, though, you can still use Ruby on Rails effectively. The interfaces between the front end (the browser’s HTML, CSS, and JavaScript) and the back end (Ruby, and the Rails framework) are well defined, so you don’t need to understand both sides if you want to focus on one or the other.

If you’re a web designer or front-end developer, you can learn how to use the Ruby on Rails template system, and how to write little bits of embedded Ruby code in your view files. This will make you a much better partner for a back-end developer, since you can work directly on the Rails application files instead of delivering HTML and CSS that someone else has to integrate.

So whether you’re approaching Ruby on Rails as a front-end or back-end developer, on which projects should you consider using it?

The “sweet spot”

Ruby on Rails is at the heart of diverse web applications and sites such as Basecamp, Blinksale, 43Things, Odeo, Revolution Health, Twitter, YellowPages.com, and A List Apart. The enthusiasm for Rails extends to many of the largest web companies. Yahoo, eBay, Amazon, and AOL all have Ruby on Rails projects, and ThoughtWorks is creating enterprise applications in Rails. But for all the diversity of Ruby on Rails applications, the ones that are best-suited to the framework have a few key things in common.

A website or web service is most appropriately implemented with Ruby on Rails when it has the following three characteristics:

  • It is a database-backed website or web service large enough to justify the overhead of a powerful framework.
  • It has unique needs that aren’t well met by a typical CMS. (If Joomla or Drupal does everything you need, such systems may be a better choice.)
  • It is a new application, allowing developers to start fresh with the database and software architecture.

This is the “sweet spot” for Ruby on Rails applications. Applications that share these characteristics can probably be built much more quickly with RoR than with PHP, .NET, or Java, once the investment required to learn Rails has been made.

Productivity boosts

One of the main reasons Ruby on Rails increases productivity is that it makes building new applications, adding features, and making tweaks much easier. The combination of the language (Ruby) and the framework (Rails) means you can do more with less code. Less code--and better-structured code--means changes are relatively painless, so you can iterate and experiment more readily. This leads to better sites, and, hopefully, more fun building them.

Of course, adopting a major new tool requires an investment of time that can’t be taken lightly. If you’re focused on a single project, it often isn’t justifiable. But if you expect to keep building websites for some time, and you’re building sites of significant complexity, a short-term investment in learning Ruby on Rails will pay off in the long term.

To understand why I believe you can do more with less effort using Ruby on Rails, let’s start with a quick look at Ruby.

Meet Ruby

Ruby is a modern, object-oriented language. In any Ruby program, everything is an object. Ruby is also a dynamic language, which means a variety of things:

  • Ruby is interpreted dynamically (like PHP), so there is no compilation (as there is with C or Java.) This speeds up iterative development.
  • In Ruby, variables are dynamically assigned a type when they are used, eliminating all the code you must write in most other languages to define and set up variables.
  • A Ruby program can generate code dynamically, modifying itself as it executes. Rails uses this capability internally to deliver its “magic,” which you can simply enjoy. (You don’t need to understand how these techniques work.)

Ruby is a wonderfully clean language to read and write, but its benefits go beyond that. Because Ruby can be powerfully extended, the Rails framework is able to turn it into a sort of special-purpose language for building web applications.

While Ruby (a language) and Rails (a framework) are separate things, they complement and depend on each other in many ways. All Ruby on Rails applications are written in Ruby, and the character of Ruby has a big influence on Ruby on Rails applications. There are frameworks, such as CakePHP, that bring many of Rails’ ideas to other languages. But the power and flexibility of Ruby makes Rails cleaner and more flexible than many other frameworks. If you’re going to make the investment in learning a framework, learning Ruby while you’re at it isn’t that big a hurdle, and the payoff is considerable.

The Rails approach

Many websites are built without any application framework at all: you just write the code you need and borrow bits from various places when you can. That’s fine for small sites, but it can quickly get out of control, resulting in reams of messy code that is hard to understand and to maintain.

With a framework such as Ruby on Rails, a lot of decisions about how to structure your code are already made for you and you also have a powerful set of libraries at your disposal.

Another important characteristic of Rails is that it organizes each application around a model-view-controller (MVC) structure. MVC, a well-established pattern for organizing software projects, gives all your code a consistent structure, which helps a lot when you’re working on multiple sites, or bringing in someone new to work on a site. It also provides separate files, with clean interfaces, that can be split between front-end and back-end developers.

Databases and objects

Ruby on Rails is designed to be used to build database-backed applications, and many of its core components focus on interacting with databases. The heart of Rails is a library called Active Record, which implements something called object-relational mapping (ORM). With ORM, you can work with software objects that represent your data and let the Active Record library take care of communicating with the database.

This may sound mysterious in the abstract, so let’s make it concrete. Even without knowing any Ruby--or anything about object-oriented programming--I bet you can make sense out of the following code examples, which are pieces of actual Ruby on Rails code.

Suppose you have a bookstore site and you want to add a new book. You could write:

newbook = Book.new

You’re telling the “Book” class that you want an empty book object, named “newbook.” You can set the title, or any of its other attributes, in an intuitive way:

newbook.title = "Angle of Repose"
newbook.author = "Wallace Stegner"

At this point, you have an object in memory. All it takes is:

newbook.save

...and your new book has been written to the database. Active Record generates the SQL to tell the database to insert the record. You can add validations on all the fields and generate descriptive error messages with just a few more lines of code.

Now you want to find that book out of the millions in your database. Just write:

angle_of_repose = Book.find_by_title "Angle of Repose"

...and you have an object, which you’ve named “angle_of_repose,” that has all the information from the appropriate database record.

There’s a little more to it, but not that much; working with software objects that reflect the information your site deals with is a natural and powerful approach. In RoR, you have a rich set of software objects that correspond to your database tables, and these objects make up the “model” layer of the model-view-controller system.

Your code interacts with the model objects, and Active Record creates the SQL to make the database do what you want. You don’t have to write any SQL to work with the database. And since none of your code communicates directly with the database, you can switch from one database engine to another by simply changing a configuration setting.

Views and controllers

To create web pages, Rails provides a template system that makes it easy to use consistent page structures, to insert common components without repeating their code, to render information that comes from the database, and to display and process forms. These templates constitute the “view�? layer of the model-view-controller system.

If you’re a front-end developer, this is the part of Rails you should focus on. You can simply assume that your “view file” will be handed variables that contain whatever information you need to display. Just as PHP files are a mix of PHP code and HTML, a typical Rails view is a mix of Ruby and HTML. Continuing with our bookstore example, here’s a snippet of view code that displays the title and author of a book:

 

<%= book.title %>

 

<%= book.author %>

The Ruby code is marked by <%= and %>; the rest is HTML. The HTML and the output of the Ruby code are combined to create the web page.

Rails has integrated support for the Prototype and Scriptaculous JavaScript libraries, plus a great facility called Ruby JavaScript (RJS), for building Ajax interfaces. You can write almost everything in Ruby, including code that is eventually executed by the browser as JavaScript (the Rails framework handles the translation.)

A “controller” is a piece of Ruby code whose primary job is to communicate with the model to prepare the data needed by the view. Any information that the view needs is assembled by the controller in a set of variables before invoking the view. The controller also responds to Ajax requests after the page has loaded. Controllers provide a variety of other functions as well, from user authentication to error handling.

“Convention over Configuration”

Rails tries hard to provide reasonable defaults for almost everything. Following a philosophy called Convention over Configuration, Rails almost entirely eliminates configuration files.

If you follow the Rails conventions, an amazing amount of stuff, from routing requests to the correct controller and view, to validating form data and displaying error messages, just works. Compared with most other languages and frameworks, it takes less code to accomplish most common tasks.

The Convention over Configuration approach is sometimes frustrating for newcomers, especially if they try to learn from an existing application, because there are hidden assumptions behind much of the code. The assumptions are what make the code simpler, but they can be confusing when you don’t know them. After you learn the Rails conventions, though, everything in Rails makes more sense. And when you’re building a new site, you have the wind at your back, because so much is already defined for you.

It’s not perfect

Rails does have its drawbacks. These weak points are minimized for applications that fall within the Rails sweet spot I described earlier, but they can be big issues at the fringes.

Ruby is slower than most other languages. This is likely to change this year, but for now, it is a disadvantage--for those few applications in which processing time is actually an issue. In reality, this is a non-issue for the vast majority of websites.

The overhead of the MVC framework can also slow things down. With a little attention, though, most Rails applications can be made to perform very well. Model requests often need tuning to reduce the number of database accesses required. You can often eliminate database requests entirely: Rails includes a powerful caching system, so pages can frequently be created once and delivered many times.

Rails applications are also more trouble to host than PHP applications. Because of the size of the Rails framework code, it has to be kept in memory all the time, not loaded in response to a request. You need 100–200 MB of dedicated RAM to host even a low-traffic Rails application. With PHP applications, in contrast, you can host hundreds of applications on a single server, because they don’t occupy any memory when they aren’t being accessed.

Because of these server requirements, shared hosting of Rails applications is generally problematic. A VPS (virtual private server) is usually the best choice. Setting up a Rails server can be more complex than for PHP. This was an issue a year or two ago, but now there are many Rails-oriented hosting companies that provide turnkey solutions.

Another result of these server requirements is that Ruby on Rails hosting tends to be more expensive than for other platforms and languages. If you’re in the Rails sweet spot, your application is significant enough that the incremental hosting cost is insignificant compared to the value you get from using Rails.

The learning curve

The complexity of Rails can make it hard for a beginner to get started: it takes months to become familiar with all of Rails. But you can get started by first learning just enough to build a basic Rails site. As you begin working with it, you’ll pick up new skills and knowledge as you need it.

People come to building websites in various ways and from different backgrounds, but most of them fall into one of two categories:

  • People who have an idea for a site they want to build and learn just enough technology to build it.
  • Programmers who see websites as just another kind of program.

Ruby on Rails was built by programmers, for programmers. So if you come to it from a professional software development background, it will feel a lot more familiar than if you come from web design.

If you’re not a software developer, there’s more to learn, but it’s not beyond your reach. Learning the parts of Ruby, and some bits of object-oriented programming, that you need to know to use Rails is not difficult. To start building applications using the Rails framework you only need to know how to use a limited subset of Ruby’s capabilities.

You can leave the advanced Ruby coding to those who work on the framework itself. You don’t need to understand much about how the internals of Rails works, or the techniques (such as metaprogramming) that it uses internally.

The Rails ecosystem includes many practices that come from the software development world, including use of source-code control systems, an automated testing framework, documentation tools, and deployment scripts. If you’ve been doing ad-hoc web development, these may be foreign concepts, but they can bring a lot of sanity into your work life once you become comfortable with them.

What to learn when

The art of learning Rails is figuring out just what you can ignore at which stage of your education so you can grapple with a few things at a time, instead of with all the diverse technologies that make up a Rails application. (One easy way to get started learning Ruby on Rails is with the "free online course":http://www.BuildingWebApps.com/learning_rails produced by the author of this article.)

Start by learning the basics of Ruby. You don’t need to go too deep, but you need to know the basics before you can effectively develop with Rails. Rails code looks almost like markup, and it is tempting to think of it as such, but you need to make the shift to thinking of your site as a program that emits web pages, rather than as a set of files that are web pages.

If you’re focused on the front end, learn how layouts, view templates, and partials work. If you’re working with a back-end developer, they’ll take care of the model and controller layers and provide your views with variables packed with just the data you need.

At first, you can ignore Ajax; it’s a largely separate layer that can make a big improvement in the user experience, but it really is optional. So you can put RJS, Prototype, and Scriptaculous aside when you’re learning Rails. Add on a layer of Ajax sophistication once you’re comfortable with the basics.

If you’re a back-end developer, concentrate on learning how to model your application domain as a set of resources, create your database tables, and use the resulting objects. The Rails framework is wide and deep, so it takes time to learn thoroughly, but you don’t need to use very much of it to get started.

While you’re learning Rails, you can ignore testing and all its associated complexities, even though it gets a lot of attention in discussions of Rails. When you’re further along, come back to it--but don’t let it slow down your initial learning or add to your cognitive load.

And you’re off!

Once you’re up to speed, Ruby on Rails will become an old friend. With this powerful set of tools at your fingertips, you’ll be more productive than ever.

By being able to do more with less code, you’ll build better sites and have more fun doing it. There’s no looking back.

Illustration by Kevin Cornell

Source : http://www.alistapart.com/articles/creatingmoreusinglesseffortwithrubyonrails/

How to Pass Params to Named Scope in Rails

Hi guys :)

In my previous post create named scope in rails, I told you about named scope in rails, what excess of named scope,how to create and how to use it. Now i will tell you, how to pass params to named scope in rails. For example, we will search users by user_name, first_name, last_name, email and city. Most of us, will create in the controller like this :

 

1
2
3
4
5
6
class UsersController < ApplicationController
  def search
      @users = User.where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%", "%#{params[:keyword]}%"])
  end
end

 

That’s will work correctly, but that’s not recomended by rails development. I think the best way to do it is to create named scope and pass the params to named scope. Please look below, how to pass params to named scope in rails.

In user model :

1
2
3
4
5
class User < ActiveRecord

   scope :search, lambda{|keyword| where(["user_name LIKE ? OR first_name LIKE ? OR last_name LIKE ? OR email LIKE ? OR city LIKE ?",
      "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%", "%#{keyword}%"])}
end

In user controller :

1
2
3
4
5
class UsersController < ApplicationController
  def search
      @users = User.search(params[:keyword])
  end
end

Source : http://whatisrubyonrails.com/how-to-pass-params-to-named-scope-in-rails

How to Create Named Scope in Rails

Named scope used to specify commonly used sql queries which can be define as method on model or on the association objects. With named scope, you can use every that have been included ActiveRecord method such us joins, select, where and etc.

Most of us start out writing our queries directly in the controllers, like this :

1
2
3
4
5
6
class  ArticleController < ApplicationController

  def article_today
    @articles = Article.where(["created_at > ?", Time.now.beginning_of_day])
  end
end

That’s works, but it’s broken cardinal role of Rails development. Rather than we embedding sql query in our controller to find article which created today in our site, much better to write something code called named scope in model which would return a collection of Article objects. To create a scope, we use the named_scope method in Rails 2 and scope method in Raials 3 above inside the class model.

Rails 2 :

1
2
3
4
class Article < ActiveRecord::Base

 named_scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Rails 3 above :

1
2
3
4
class Article < ActiveRecord::Base

 scope :today, where(["created_at > ?", Time.now.beginning_of_day])
end

Then in our controller we call :

1
2
3
4
5
calss ArticlesController < ApplicationController
 def article_today
 @articles = Article.today
 end
end

That’s would return a collection of Article objects which created today. It’s look DRY query. In addition we also use scope to get object with join table. Please look below :

Rails 2 :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 named_scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Rails 3 above :

1
2
3
4
5
class User < ActiveRecord::Base
 has_many :addresses

 scope :group_by_city, joins(:addresses).where(["addresses.city = ?", "Jakarta"])
end

Source : http://whatisrubyonrails.com/create-named-scope-in-rails