Wednesday, August 21, 2013

Rails 4 - Scope

In rails 4, scopes should take a proc object or a block. Take an example this User model
Class User < ActiveRecord::Base
  attr_accessor :name,:age,:status

  def initialize(name, age)
    @name = name
    @age = age
  end
end
I would like to make default scope based on status 'user' and admin scope based on status 'admin'. In rails 3, I can make scope like this
#Rails 3
scope :admin, where(status: 'admin')
default_scope where(status: 'user')

Rails 4, I can make scope this way
#Rails 4
default_scope { where(status: 'user') } #  block
#default_scope ->{ where(status: 'admin) } #Proc valid
scope :admin, ->{ where(status: 'admin') }
If we try to use scope without(see rails3 examples) passing proc or block in Rails 4, it triggers DEPRECATION WARNING message.

Rails 4 - Finders

Old-Style finders are deprecated
In Rails 4, Old-Style finders are deprecated. Consider User model with name, age members
Class User < ActiveRecord::Base
  attr_accessor :name,:age

  def initialize(name, age)
    @name = name
    @age = age
  end
end

In this class, If we want find user with name of 'foo'. See the difference in rails 3 and rails 4 call
#Rails 3
User.find(:all, conditions: { name: 'foo' })
#Rails 4
User.where(name: 'foo')

In rails 4, you will get DEPRECATION WARNING: Calling #find(:all) is deprecated. You can call #all directly instead or build a scope instead of using finder options.

Dynamic finders that return collections are deprecated
#Rails 3
User.find_all_by_name('foo')
#Rails 4
User.where(name: 'foo')

In Rails 4 alerts DEPRECATION WARNING if we use dynamic method(User.find_all_by_name). Preferable alternative option is User.where(...).all