Posts Tagged ‘rails3’

Single table inheritance in Rails3

Posted: March 18, 2011 in Rails
Tags: ,

Active Record allows inheritance by storing the name of the class in a column that by default is named “type” (can be changed by overwriting Base.inheritance_column). This means that an inheritance looking like this:

class Company < ActiveRecord::Base; end
class Firm < Company; end
class Client < Company; end
class PriorityClient < Client; end

When you do Firm.create(:name => “37signals”), this record will be saved in the companies table with type = “Firm”. You can then fetch this row again using Company.where(:name => ’37signals’).first and it will return a Firm object.

If you don’t have a type column defined in your table, single-table inheritance won’t be triggered. In that case, it’ll work just like normal subclasses with no special magic for differentiating between them or reloading the right type with find.

Note, all the attributes for all the cases are kept in the same table. Read more: singleTableInheritance

config.use_transactional_fixtures = true

Posted: March 13, 2011 in Rails

if you set config.use_transactional_fixtures = false and you are using ActiveRecord with rspec, you will find that any operates of test database can not rollback.

So, make sure config.use_transactional_fixtures = true if you using ActiveRecord

reload routes with spork each run

Posted: March 13, 2011 in Rails
Tags: ,

Default(spork -d) not reload routes. So add routes to each_run block.

Spork.each_run do
  # This code will be run each time you run your specs.
  require File.expand_path("../../config/routes", __FILE__)

Caching and Performance

Posted: March 11, 2011 in Rails
Tags: ,

Just some notes after reading “The Rails3 Way” chapter seventeen and Caching with Rails.

There are three types of view caching in Rails:

  • Page caching: The output of an entire controller action is cached to disk, with no further involvement by the Rails dispatcher.
  • Action caching: The output of an entire controller action is cached to disk, but the Rails dispatcher is still involved in subsequent requests, and controller filters are executed.
  • Fragment caching: Arbitrary bits and pieces of your page’s output can be cached to disk to save the time of having to render them in the future.

By default, the page cache directory is set to Rails.public_path (which is usually set to the public folder) and this can be configured by changing the configuration setting config.action_controller.page_cache_directory. Changing the default from public helps avoid naming conflicts, since you may want to put other static html in public, but changing this will require web server reconfiguration to let the web server know where to serve the cached files from, other than you will make rails rewriting the cache (Means don’t have any cache!).

The Page Caching mechanism will automatically add a .html extension to requests for pages that do not have an extension to make it easy for the webserver to find those pages and this can be configured by changing the configuration setting config.action_controller.page_cache_extension.

Note: Page caching ignores all parameters. For example /products?page=1 will be written out to the filesystem as products.html with no reference to the page parameter. Thus, if someone requests /products?page=2 later, they will get the cached first page. Be careful when page caching GET parameters in the URL!

Action Caching works like Page Caching except for the fact that the incoming web request does go from the webserver to the Rails stack and Action Pack so that before filters can be run on it before the cache is served. This allows authentication and other restriction to be run while still serving the result of the output from a cached copy.

Fragment Caching allows a fragment of view logic to be wrapped in a cache block and served out of the cache store when the next request comes in.

Action Cache and Fragment Cache default path: your_project/tmp/cache (ActiveSupport::Cache::FileStore)


Cache sweeping is a mechanism which allows you to get around having a ton of expire_{page,action,fragment} calls in your code. It does this by moving all the work required to expire cached content into an ActionController::Caching::Sweeper subclass.

It’s important to note that SQL query caches are created at the start of an action and destroyed at the end of that action and thus persist only for the duration of the action.

You can access these cache stores at a low level for storing queries and other objects."city")   # => nil
Rails.cache.write("city", "Duckburgh")"city")   # => "Duckburgh"

Conditional GET support

class ProductsController < ApplicationController

  def show
    @product = Product.find(params[:id])

    # If the request is stale according to the given timestamp and etag value
    # (i.e. it needs to be processed again) then execute this block
    if stale?(:last_modified => @product.updated_at.utc, :etag => @product)
      respond_to do |wants|
        # ... normal response processing

    # If the request is fresh (i.e. it's not modified) then you don't need to do
    # anything. The default render checks for this using the parameters
    # used in the previous call to stale? and will automatically send a
    # :not_modified.  So that's it, you're done.

class ProductsController < ApplicationController

  # This will automatically send back a :not_modified if the request is fresh,
  # and will render the default template (product.*) if it's stale.

  def show
    @product = Product.find(params[:id])
    fresh_when :last_modified => @product.published_at.utc, :etag => @product

Action Mailer

Action Mailer Configuration for sendmail

config.action_mailer.delivery_method = :sendmail
# Defaults to:
# config.action_mailer.sendmail_settings = {
#   :location => '/usr/sbin/sendmail',
#   :arguments => '-i -t'
# }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true

Action Mailer Configuration for GMail

config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
  :address              => "",
  :port                 => 587,
  :domain               => '',
  :user_name            => '<username>',
  :password             => '<password>',
  :authentication       => 'plain',
  :enable_starttls_auto => true  }

Model User should devise :confirmable

class User < ActiveRecord::Base
  devise :database_authenticatable, :confirmable, :lockable, :recoverable,
         :rememberable, :registerable, :trackable, :timeoutable, :validatable,

  attr_accessible :email, :password, :password_confirmation

task :setup => ['db:drop', 'db:create', 'db:migrate', 'environment'] do
  user = User.create! do |u| = ''
    u.password = 'user123'
    u.password_confirmation = 'user123'
  puts 'New user created!'
  puts 'Email   : ' <<
  puts 'Password: ' << user.password

  admin = Admin.create! do |u| = ''
    u.password = 'admin123'
    u.password_confirmation = 'admin123'
  puts 'New admin created!'
  puts 'Email   : ' <<
  puts 'Password: ' << admin.password