Limiting columns in model association


#1

So we have this model:

class Post < ActiveRecord::Base

belongs_to :person

But when I join @post.person I only want the id and name. The docs
fleetingly mention using :select to accomplish this but there are no
examples and no explanations. I tried:

belongs_to :person, :select => [:id, :name]
belongs_to :person, :select => {:id, :name}

…without success. Could anyone explain how to use the :select
parameter? Thanks!


#2

On 3/8/07, Taylor S. removed_email_address@domain.invalid wrote:

examples and no explanations. I tried:

It’s a string, you’d need to do

belongs_to :person, :select => “id AND name”

Pat


#3

First, :select defines a string that will go directly in to the SELECT

  • FROM * WHERE clause of the SQL statements ActiveRecord uses, so “id
    AND name” will NOT work.

Second, in this particular case you probably shouldn’t be limiting the
columns on the MODEL level. Instead, defining select for the find
will do:

@posts = Post.find( :all,
                    :select => "id, name",
                    :conditions => "is_deleted = false",
                    :order => "posts.created_at DESC",
                    :include => :person)

On Mar 9, 4:24 am, Taylor S. removed_email_address@domain.invalid


#4

Does this not work with :include? Here’s my function:

@posts = Post.find( :all,
                    :conditions => "is_deleted = false",
                    :order => "posts.created_at DESC",
                    :include => :person)

and the corresponding error:

ArgumentError: Unknown key(s): select

POST.RB
class Post < ActiveRecord::Base

belongs_to :person, :select => “id AND name”


#5

Ooh… yeah, it doesn’t. :include screws up the select portion of the
query. Sorry, I missed that key in the list.

Anyway, is there a reason to limit person to id/name? At this point,
you can still do it, but you’ll have to use explicit SQL joins.

@posts = Post.find( :all,
                    :select => "posts.*, persons.id AS person_id,

persons.name AS person_name",
:join => “INNER JOIN #{Person.table_name} ON
persons.id = posts.person_id”,
:conditions => “is_deleted = false”,
:order => “posts.created_at DESC”)

Then your @posts array will have a bunch of Post objects with all
their attributes plus two new ones – person_id and person_name.

Using :include and referencing the Person model off the Post object is
much cleaner though…

On Mar 10, 3:13 am, Taylor S. removed_email_address@domain.invalid


#6

Eden Li wrote:

Ooh… yeah, it doesn’t. :include screws up the select portion of the
query. Sorry, I missed that key in the list.

Anyway, is there a reason to limit person to id/name? At this point,
you can still do it, but you’ll have to use explicit SQL joins.

The reason was just one of optimization - why load all the person data
when all I need is the name and id? But its not worth writing nasty SQL
for every :include!


#7

Eden Li wrote:

First, :select defines a string that will go directly in to the SELECT

  • FROM * WHERE clause of the SQL statements ActiveRecord uses, so “id
    AND name” will NOT work.

Second, in this particular case you probably shouldn’t be limiting the
columns on the MODEL level. Instead, defining select for the find
will do:

@posts = Post.find( :all,
                    :select => "id, name",
                    :conditions => "is_deleted = false",
                    :order => "posts.created_at DESC",
                    :include => :person)

This doesn’t work, unfortunately. Does rails even pass :select with
include?