I'm working with a legacy MySQL database that I'm trying to interact with using Rails, and I get an error when creating records:
2.7.2 :005 > HashRef.create!(hash: '00080e597c26a05197aaa4462e53cdf9847b56a4d5d47e550fdc01554434df8gg2fffsss')
TRANSACTION (0.2ms) BEGIN
HashRef Create (0.3ms) INSERT INTO `hash_ref` (`hash`) VALUES ('00080e597c26a05197aaa4462e53cdf9847b56a4d5d47e550fdc01554434df8gg2fffsss')
TRANSACTION (4.7ms) COMMIT
Traceback (most recent call last):
2: from (irb):4
1: from (irb):5:in `rescue in irb_binding'
TypeError (no implicit conversion of String into Integer)
It would appear that this is because the DB table has a string column named hash
(the primary key) which is conflicting with some Rails stuff.
CREATE TABLE `hash_ref` (
`hash` varchar(512) NOT NULL,
`cipher` varchar(512) DEFAULT NULL,
`clear` varchar(512) DEFAULT NULL,
`record_insert_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`hash`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I can alias the attribute, but this raises the same error when writing.
alias_attribute :my_hash, :hash
Unfortunately renaming the column is not an option at this point.
I would have thought there was some way to proxy a column name, so I can refer to it as my_hash
in the code but when it queries the DB it uses hash
.
I've seen this monkey patch proposed in another answer, which seems to work, but I'm wondering if it's safe to do:
class << self
def instance_method_already_implemented?(method_name)
return true if method_name == 'hash'
super
end
end
There's also a gem suggested, but it hasn't been updated for many years:
https://github.com/bjones/safe_attributes
The only thing I can think of is to use raw SQL for writing to this DB, but it's very awkward when writing RSpec tests to not be able to use the model or factories.
Thanks for any help