I'm new to Rails but this seems pretty straightforward. I have a model called Game generated like this:

rails generate model Game name:string year:integer manufacturer:string notes:string is_active:boolean

I've loaded the table with some data, and I am trying to fetch all of the rows where is_active is true. I'd like my model to be something like:

class Game < ActiveRecord::Base
  scope :active, where(:is_active => 1)

My problem is whenever I try to bind to the Game.active query I get an error. It's the same error in the rails console or if I try to set it to a variable in the controller. The error is:

undefined method `call' for #<Game::ActiveRecord_Relation:0x007ffadb540aa0>

When running in the console I see:

irb(main):001:0> Game.active
NoMethodError:   Game Load (0.2ms)  SELECT `games`.* FROM `games`  WHERE `games`.`is_active` = 1
undefined method `call' for #<Game::ActiveRecord_Relation:0x007fcdca66b800>
    from /home/dcain/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activerecord-4.1.0/lib/active_record/relation/delegation.rb:136:in `method_missing'

Rails 4+ requires named scopes to be a lambda and not just a simple Relation.

Change the old version

scope :active, where(is_active: true)

to the lambda version

scope :active, lambda { where(is_active: true) }

or even shorter to

scope :active, -> { where(is_active: true) }

For more information about named scopes and how to pass parameters, I suggest reading about Scopes in the Rails Guide

  • Furthermore it should be where(is_active: true) since it's a boolean field (Rails handles the conversion from true to 1) – Stefan Apr 28 '14 at 10:20
  • 2
    @Stefan: I agree with you, when is_active is a boolean than true should be used instead of 1. I do not want to discuss the different hash syntaxes here. Both syntaxes are valid and have its pros and cons. – spickermann Apr 28 '14 at 10:29
  • Two years later I agree with you: We should use the newer hash syntax in scopes. – spickermann Mar 28 '16 at 10:20

Your Answer

