Selecting only a subset of columns

Hi.

In many areas in the AR API you can specify a :select option to select
only a subset of columns.

Is there any way to change the default selected columns (which is “*”)
to a subset of columns for a whole model.

such that when I write Model.find(1) it gives me an instance with
only, say 3 (out of 7), columns. and to fetch all columns I have to
write Model.find(1, :select => “*”)

Thanks in advance.

Jarl

You may try adding a "default_scope :select=>‘id, name, etc’ " to
your model. This would accomplish what you are looking for, but I
can’t assure it won’t give you problems later in your code. Maybe you
should add a regular named_scope with parameters and use it instead of
‘find’.

Anyway, you should always add the ‘id’ attribute to that list, just in
case you want to reload a particular object you found; if you don’t
have id, ‘.reload’ won’t work.

On 7 September 2010 08:57, Jarl F. [email protected] wrote:

write Model.find(1, :select => “*”)
Can you do that in a default_scope for the model? I have not tried it.

Colin

Jarl F. [email protected] writes:

DEFAULT_SELECT = “#{column_names.reject{|c| c =~ /image/ }.map{|c|
“"orders"."#{c}"”}.join(', ')}”.freeze
default_scope :select => DEFAULT_SELECT

Warning to others:

This is not a good solution, it gives problems upon deploying an
application at a clean environment. The problem arise when doing rake
db:migrate, since column_names tries to get column names from the
database at a time where the table does not exist!

I have not found a better way (yet)

Jarl

Thanks Xuan and Colin for your attention.

Xuan [email protected] writes:

You may try adding a "default_scope :select=>‘id, name, etc’ " to
your model. This would accomplish what you are looking for,

That was exactly what I was looking for.

My actual implentation looked like this in my AR class

DEFAULT_SELECT = “#{column_names.reject{|c| c =~ /image/ }.map{|c|
“"orders"."#{c}"”}.join(', ')}”.freeze
default_scope :select => DEFAULT_SELECT

And the very few places that I need all columns, I have added :select
=> ‘*’ to the find call

but I can’t assure it won’t give you problems later in your
code. Maybe you should add a regular named_scope with parameters and
use it instead of ‘find’.

Fortunately I have thousands of tests to asure that :slight_smile:

Jarl

On 15 October 2010 14:26, Jarl F. [email protected] wrote:

database at a time where the table does not exist!
I think you can avoid the problem in the migration by defining the
model class inside the migration, so something like:

class YourMigration < ActiveRecord::Migration
class TheProblematicClass < ActiveRecordBase;
end

def self.up

This stops your class definition being used by the migration so your
default scope is never used. In fact I believe it is good to do this
if you ever reference an AR class in the migration as the code for the
class may not match the current state of the db during migrations.

Colin

Colin