rainslg
rainslg

Reputation: 455

Creating a scope on an ActiveRecord Model

I have a ActiveRecord model called Panda with a column called variant, which can consist of values like ‘bam-abc’, ‘bam-123’, ‘boo-abc’ and ‘boo-123’ I want to create a scope which selects all records where the variant starts with ‘boo’.

In the console, I can select those records (starting with ‘boo') with the following:

Panda.select{|p| p.variant.starts_with? 'boo'}

Is there a way to turn that into a scope on the Panda class? I need to be able to do a 'to_sql' on the scope for my RSpec tests.

Upvotes: 0

Views: 90

Answers (2)

dezhan
dezhan

Reputation: 50

Add the line below to the Panda class

scope :boo, -> { where('variant LIKE ?', 'boo%') }

You can then use Panda.boo to get all the records with variant starting with boo. Panda.boo.to_sql will give you the sql

Upvotes: 0

mu is too short
mu is too short

Reputation: 434595

You'd want to use a scope that sends a LIKE into the database, something like:

scope :boos, -> { where('pandas.variants like ?', 'boo%') }

or equivalently, use a class method:

def self.boos
  where('pandas.variants like ?', 'boo%')
end

Then you can say things like:

Panda.boos.where(...)
Panda.where(...).boos
Panda.boos.where(...).to_sql
Panda.where(...).boos.to_sql

You only need to use the pandas prefix on the column name if you think you'll be doing JOINs with other tables that might leave the variant name ambiguous. If you'll never be doing JOINs or you'll only ever have one variant column in your database then you could use one of:

scope :boos, -> { where('variants like ?', 'boo%') }

def self.boos
  where('variants like ?', 'boo%')
end

Upvotes: 1

Related Questions