14

I am accessing a database that I can't change and it has a column named valid defined. Anytime I try to access an attribute, I get this exception:

valid? is defined by ActiveRecord (ActiveRecord::DangerousAttributeError)

The exception makes sense, but since I'm not able to change the database, how can I get around this error?

I tried "overriding" the attribute, but I don't know how to remove the original column. I can successfully call this valid_column method, but any time I try to access another attribute defined in the database, I get the same exception. It still seems to be trying to map the valid column.

  def valid_column=(valid)
    write_attribute(:valid, valid)
  end
  def valid_column
      read_attribute(:valid)
  end

I'm not sure if it matters, but here are the details of my environment:

  • Windows Ruby 1.8.6
  • Informix database on a Linux server
  • activerecord (2.3.4)
  • activerecord-informix-adapter (1.0.0.9250)
  • ruby-informix (0.7.1)

Thanks in advance!

Amokrane Chentir
  • 29,907
  • 37
  • 114
  • 158
Michael
  • 1,919
  • 2
  • 16
  • 26

4 Answers4

11

Try this:

class MyTable < AR:Base
   class << self
     def instance_method_already_implemented?(method_name)
       return true if method_name == 'valid'
       super
     end
   end
end

It's a hack, and it might not work in rails 3, but it could fix the problem for now.

I found it on the ruby on rails mailing list

If you wanted, you could also look at datamapper, which handles these sort of things somewhat more sanely.

BaroqueBobcat
  • 10,090
  • 1
  • 31
  • 37
  • 1
    You might need to change `return true if method_name == 'valid'` to `return true if method_name == 'valid?'` in order to get it to work. I did. – Jason Swett Dec 04 '12 at 16:42
4

Use safe_attributes - https://github.com/bjones/safe_attributes . It works perfectly out of the box:

class WebsiteUser < ActiveRecord::Base
    establish_connection 'cf_website'
    set_table_name 'nc_users'
    bad_attribute_names :hash    
end
nicholasf
  • 281
  • 2
  • 6
3

Without worrying about ActiveRecord's reserved attributes, just add a gem in your gemfile and the gem will take care of name collisions automatically.

gem 'safe_attributes'

http://goo.gl/OO2H7

RAJ
  • 9,697
  • 1
  • 33
  • 63
  • what if the object is already created? I'm getting an error on my object when trying to access `myobj.association`. The object was created prior to adding the gem to my gemfile. Thanks. – daveomcd Jun 02 '13 at 17:09
2

For reads you might be able to use SQL's select-as statement. Not sure if the following will work, but a default scope may make this easily do-able.

class MyRecord < ActiveRecord::Base
    default_scope :select=> 'valid as valid_column'
end
jrhicks
  • 14,759
  • 9
  • 42
  • 57