Hey there
I have this small issue with trying to get Rails to work with a legacy
MS SQL database. I’ve setup the mssqlclient adapter correctly (can
create models), and I’m now trying to create an Item MVC from an “Item”
table in the legacy database schema. My Item.rb model looks like this:
class Item < ActiveRecord::Base
We override the table name, since Rails uses pluralization by
default:
set_table_name(‘Item’)
We also override the primary key column, since we can’t use the
auto incremented id field:
set_primary_key(‘Itemnumber’)
Here’s another bid:
#set_primary_key :itemnumber
#attr_accessor :itemnumber
#before_validation_on_create ‘self.id = @itemnumber’
Okay, one more try:
def before_create
self.id = Itemnumber
end
def save_key(key) #…manual PK
@key = key
end
def before_create #…manual PK
self.id = @key
end
def update
if self.id == @key #…Original ActiveRecord::Base
connection.update(
"UPDATE #{self.class.table_name} " +
"SET #{quoted_comma_pair_list(connection,
attributes_with_quotes(false))} " +
“WHERE #{self.class.primary_key} = #{quote(id)}”,
“#{self.class.name} Update”
)
else #…manual PK
connection.update(
"UPDATE #{self.class.table_name} " +
"SET #{self.class.primary_key} = #{quote(@key)}, " +
"#{quoted_comma_pair_list(connection,
attributes_with_quotes(false))} " +
“WHERE #{self.class.primary_key} = #{quote(id)}”,
“#{self.class.name} Update”
)
self.id = @key
end
return true
end
end
As you can see, I have been trying a couple of different things. The
connection works okay, and queries get sent to the MS SQL Server
alright, there’s just this little catch (output from
http://localhost:3002/items/show/9780672328930):
ActiveRecord::StatementInvalid in ItemsController#show
ActiveRecord::StatementInvalid: System.IndexOutOfRangeException: Index
was outside the bounds of the array.
at MsSqlClient.Helpers.ToRubyString(String string)
at MsSqlClient.Helpers.CastToRubyObject(Type clr_type, Object
object)
at MsSqlClient.Helpers.convert_reader_to_rowset(SqlDataReader
reader)
at MsSqlClient.?A0x1551cb11.c_MsSqlAdapter_select(UInt32 self,
UInt32 query): SELECT TOP 1 * FROM Item WHERE (Item.Itemnumber =
‘9780672328930’)
RAILS_ROOT: ./script/…/config/…
Application Trace | Framework Trace | Full Trace
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/active_record/connection_adapters/abstract_adapter.rb:120:in
log' lib/mssqlclient/mssqlclient_adapter.rb:319:in
select’
lib/mssqlclient/mssqlclient_adapter.rb:86:in select_all' #{RAILS_ROOT}/app/controllers/items_controller.rb:16:in
show’
-e:4
Request
Parameters: {“id”=>“9780672328930”}
Show session dump
Response
Headers: {“cookie”=>[], “Cache-Control”=>“no-cache”}
he Itemnumber given in the url exists, and the sql query included in
the error output yields the correct row when executed on the server.
The Itemnumber is a varchar(20) field containing an EAN number (thus
not usable for auto incrementation). My guess is that Rails maps the id
field correctly to the Itemnumber column, but that it still considers
id to be an integer, whence the out of range exception on this very
large number. Confirm?
Can anyone help me with how I get the last bits of this issue to fall
into place? I have id mapped to Itemnumber, but I believe I still need
to make ActiveRecord/Rails understand that this is not an integer
field, and that its value cannot be generated automatically, it must be
input by the user.
I’m sorry if my questions are a little lame, I’ve only read the Up and
Running with Ruby on Rails book so far, and it doesn’t do anything
“non-kosher” with ActiveRecord, so I’m a little lost
Thanks in advance for any help!
Daniel