Date: 2013-02-27 21:35
Sender: Nathan Wiebe
First create a new database (db2 v9.7.4 on Linux/Windows):
>db2 create database ibmdbex
Now create some tables with 1 row each:
>create table schema1.table1 (
id integer,
name1 varchar(100),
description1 varchar(255)
);
>insert into schema1.table1 (name1,
description1)values('test1', 'this is a test1');
>create table schema2.table2 (
id integer,
name2 varchar(100),
description2 varchar(255)
);
insert into schema2.table2 (name2,
description2)values('test2', 'this is a test2');
create a new rails (v3.1.12) app:
>mkdir ibmdbex
>cd ibmdbex
>rails new .
Add ibm_db to Gemfile.
>bundle install
Setup a dev environment in config/database.yml, specifing
the schema to match schema1.table1 above:
development:
adapter: ibm_db
database: ibmdbex
host: 127.0.0.1
username: user
password: secret
schema: schema1
Now define two models, one with the same schema as specified
in config/database.yml (Table1) and other other not
(Table2):
app/models/table1.rb:
class Table1 < ActiveRecord::Base
self.table_name = 'table1' #table in schema specified in
database.yml
end
app/models/table2.rb:
class Table2 < ActiveRecord::Base
self.table_name = 'schema2.table2' #table NOT in schema
specified in database.yml
end
Now get into the rails console and see what the models know
about the columns in their backing tables:
---
rails c
irb(main):007:0> Table1.columns
=> [#
<ActiveRecord::ConnectionAdapters::IBM_DBColumn:0x3a62930
@name="id", @sql_type="integer", @null=true,
@limit=nil,
@precision=nil, @scale=nil, @type=:integer, @default=nil,
@primary=false, @coder=nil>, #<Ac
tiveRecord::ConnectionAdapters::IBM_DBColumn:0x3a61fe8
@name="name1", @sql_type="varchar(100)",
@null=true,
@limit=100, @precision=nil, @scale=nil, @type=:string,
@default=nil, @primary=false, @coder=nil>, #<Act
iveRecord::ConnectionAdapters::IBM_DBColumn:0x3a61fa0
@name="description1", @sql_type="varchar(255)",
@null=true,
@limit=255, @precision=nil, @scale=nil, @type=:string,
@default=nil, @primary=false, @coder=nil>]
irb(main):008:0> Table2.columns
=> []
---
As you can see from the above, the columns for Table1 are
known, but not Table2.
Similarly, .arel_table doesn't know about any columns in
Table2, even saying that Table2 doesn't exist.
---
irb(main):001:0> Table1.arel_table
=> #<Arel::Table:0x3b37a38 @name="table1",
@engine=Table1(id: integer, name1: string, description1:
string), @columns=nil, @aliases=[], @table_alias=nil,
@primary_key=nil>
irb(main):002:0> Table2.arel_table
=> #<Arel::Table:0x4ca1138 @name="schema2.table2",
@engine=Table2(Table doesn't exist), @columns=nil, @aliases=
[], @table_alias=nil, @primary_key=nil>
---
Table2's lack of column knowledge can be seen when using the
arel .where selector. In the example below notice that
Table1 knows it's columns, but table 2 does not.
rails c
---
irb(main):003:0> Table1.where(name1: 'test1')
[1m?[35mTable1 Load (5.0ms)?[0m SELECT table1.* FROM
table1 WHERE table1.name1 = 'test1'
=> [#<Table1 id: nil, name1: "test1", description1:
"this is
a test1">]
irb(main):004:0> Table2.where(name2: 'test2')
[1m?[36mTable2 Load (6.0ms)?[0m ?[1mSELECT
schema2.table2.* FROM schema2.table2 WHERE
schema2.table2.name2 = 'test2' ?[0m
=> [#<Table2 >]
---
This lack of knowledge also affects things like casting DB2
DATE columns to ruby Date instances on SQL selects, and vice
versa on SQL inserts.
Thanks for your interest. I hope I've made myself more
clear, let me know if you'd like more detail.
Nathan |