module ActiveRecord
module ConnectionAdapters # :nodoc:
module Quoting
# Quotes the column value to help prevent
# {SQL injection attacks}[Wikipedia, the free encyclopedia
SQL_injection].
def quote(value, column = nil)
# records are quoted as their primary key
return value.quoted_id if value.respond_to?(:quoted_id)
case value
when String, ActiveSupport::Multibyte::Chars
value = value.to_s
if column && column.type == :binary &&
column.class.respond_to?(:string_to_binary)
"#{quoted_string_prefix}'#{quote_string(column.class.string_to_binary(value))}'"
# ' (for ruby-mode)
elsif column && [:integer, :float].include?(column.type)
value = column.type == :integer ? value.to_i :
value.to_f
value.to_s
else
"#{quoted_string_prefix}'#{quote_string(value)}'" #
' (for ruby-mode)
end
when NilClass then "NULL"
when TrueClass then (column && column.type
== :integer ? '1' : quoted_true)
when FalseClass then (column && column.type
== :integer ? '0' : quoted_false)
when Float, Fixnum, Bignum then value.to_s
# BigDecimals need to be output in a non-normalized form and
quoted.
when BigDecimal then value.to_s('F')
else
if value.acts_like?(:date) || value.acts_like?(:time)
"'#{quoted_date(value)}'"
else
"#{quoted_string_prefix}'#{quote_string(value.to_yaml)}'"
end
end
end
...
so i saw the method quote and the case select which returns "NULL" if
value is a NilClass
but why its NilClass?
class Advertiser < ActiveRecord::Base
set_table_name "INSERENT"
set_primary_key "INSNR"
has_many :priv_properties,
:class_name => "PrivProperty",
:foreign_key => "MAKNR"
end
produces wrong sql selelect.
so the searched value is NULL
ins = Advertiser.find(100050)
select * from objpriv where objpriv.maknr = NULL;
it should be
select * from objpriv where objpriv.maknr = 100050;
Given what you've told AR, I would expect the sql generated to be
select * from INSERENT where INSNR = 100050; since you've asked AR to
find you the instance of Advertiser with primary key value 100050 and
you've told it that the table name is INSERENT and the primary key INSNR
im a step forward. so i changed the my model see below:
class Advertiser < ActiveRecord::Base
set_table_name :inserent
set_primary_key :insnr
has_many :priv_properties,
:class_name => "PrivProperty",
:foreign_key => "MAKNR"
end
so set_table_name and set_primary_key must have a :hash? in my book,
agile webdevelopment from dhh, he wrote a normal string?
but it works if i call ins.id
there is a none nil result
so columns_hash expected a string an the code converts a hash? to_s ?
def column_for_attribute(name)
self.class.columns_hash[name.to_s]
end
now im quite happy but the association always doesnt work.
so AR creates the following sql
SELECT * FROM OBJPRIV WHERE (OBJPRIV.MAKNR = 100050.0)
i wonder, why the its a floating point number.
basicly the behavior is rigth but this, floating point number seam
to be scary?
so ins.id returns the bigdecimal and the sql statement will be filled
with the right value in the condition area
the only thing i changed, was the options under set_primary_key from
string "INSNR" to a hash :insnr
(is it the right spelling?)
You mean symbol, not hash. I've no idea why that would make a difference
the next problem is the bigdecimal typed id
standard rails created database schematas will return only the value
of id without any kind of
type information and so on
in this case, the id is mapped to "INSNR" of my legacy table and that
produces => #<BigDecimal:3fd2c8c,'0.10005E6',8(12)>
its okay, but the foreign_key is a char(10) so its a difference
between 100050 100050.0
for an integer column its no difference but it isnt proper for my
eyes
so for the current integration of the legacy tables, the bigdecimal
column should be a clear integer ...
ins.id.to_i returns the right value for the condition
additionally, if i scaffold the INSERENT table the ids also are
floating point numbers
why?
What are the types of the database columns. If you've actually declared them as big decimals what rails is doing seems reasonable, if not what you want.
yes, symbol was the right name
the column maknr is a char(10) in the table objpriv
fortunately, our databases, firebird, support sql statements
like select * from objpriv where maknr = 100050 without apostrophe
of a char(10)
select * from objpriv where maknr = 100050.0
on an integer column 100050 and 100050.0 are same
but on a char column its not the same
so thats my problem