Why all columns of joined table get instantiated as String?

Been developing in Rails for about a month and I'm still working on
grasping its subtleties.
Can someone please shed some light on this simple scenario?

## Schema ##

create_table :books do |t|
  t.string :title
  t.integer :year
end

create_table :pages do |t|
  t.integer :no
  t.references :book
end

## Models ##

Book has_many :pages
Page belongs_to :book

Then in Rails' console:

@pages = Page.all(
  :select => 'pages.id, pages.no, books.year book_year',
  :joins => :book
)

@pages.first.no.class #=> Fixnum
@pages.first.book_year.class #=> String

What I don't understand is why book_year is a String instead of a
Fixnum. Is it possible to get Book's columns correctly instantiated?

Thanks

Not that I know of. The typecasting stuff only knows about the columns
of the model itself.

Fred

Thanks, Fred. I suppose I'll stick with views and conversions.

Why not

pages = Page.all(:include => :book)

pages.first.book.year

Rick Denatale wrote:

Why not

pages = Page.all(:include => :book)

I usually need to filter by, let's say, a certain library:

@pages = Page.all(
  :select => 'pages.id, pages.no',
  :joins => :book,
  :conditions => "books.library_id = #{1}"
)

AR will generate:
SELECT pages.id, pages.no FROM "pages" INNER JOIN "books" ON "books".id
= "pages".book_id WHERE (books.library_id = 1)

So the join has already been done. Wouldn't :include make a redundant
query?

Then just change the joins to include:

Page.all(
:include => :book,
:conditions => ["books.library_id = ?", 1]
)

Which will both allow you to refer to the books fields in the where
clause, and return an collection of object graphs rather than page
object corrupted with fields they shouldn't have.

Rick Denatale wrote:

Then just change the joins to include:

Page.all(
:include => :book,
:conditions => ["books.library_id = ?", 1]
)

Which will both allow you to refer to the books fields in the where
clause, and return an collection of object graphs rather than page
object corrupted with fields they shouldn't have.

That's true, but I lose control over :select

Page.all(
  :select => 'pages.id, pages.no',
  :include => :book,
  :conditions => ["books.library_id = ?", 1]
)

...will generate:

SELECT
  "pages"."id" AS t0_r0,
  "pages"."no" AS t0_r1,
  "pages"."book_id" AS t0_r2,
  "pages"."created_at" AS t0_r3,
  "pages"."updated_at" AS t0_r4,
  "books"."id" AS t1_r0,
  "books"."title" AS t1_r1,
  "books"."year" AS t1_r2,
  "books"."library_id" AS t1_r3,
  "books"."created_at" AS t1_r4,
  "books"."updated_at" AS t1_r5
FROM
  "pages"
  LEFT OUTER JOIN "books" ON "books".id = "pages".book_id
WHERE
  (books.library_id = 1)

The real "books" and "pages" have decimal and large text columns that
are not always needed.

Could be worth considering extracting those fields into another table
and have a 1:1 link... a little messy, but saves you returning lots of
data when you only need a small part of it.