JackDanger / immutable_attributes

specify attributes within an ActiveRecord model that can be set but not modified
http://6brand.com
MIT License
24 stars 7 forks source link

immutable_attributes breaks ActiveRecord exists method #1

Open tfe opened 14 years ago

tfe commented 14 years ago

The presence of this plugin on one of my models seems to be breaking the AR exists? method. I think it's because exists only selects IDs, and when AR tries to instantiate objects with only the ID present, immutable_attributes freaks out.

In this example mymodel is the model and myattr is the immutable attribute, and also the attribute I'm passing to exists?, like so: MyModel.exists?(:myattr => 'foo').

MyModel Load (0.2ms)   SELECT "mymodel".id FROM "mymodel" WHERE ("mymodel"."myattr" = 'foo') LIMIT 1
ActiveRecord::MissingAttributeError: missing attribute: myattr
    from /Users/tfe/Sites/myapp/vendor/plugins/immutable_attributes/lib/immutable_attributes.rb:46:in `send'
    from /Users/tfe/Sites/myapp/vendor/plugins/immutable_attributes/lib/immutable_attributes.rb:46:in `setup_originals'
    from /Users/tfe/Sites/myapp/vendor/plugins/immutable_attributes/lib/immutable_attributes.rb:45:in `each'
    from /Users/tfe/Sites/myapp/vendor/plugins/immutable_attributes/lib/immutable_attributes.rb:45:in `setup_originals'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:178:in `send'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:178:in `evaluate_method'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:166:in `call'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:93:in `run'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:92:in `each'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:92:in `send'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:92:in `run'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:276:in `run_callbacks'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/callbacks.rb:344:in `callback'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1657:in `send'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:1657:in `instantiate'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/base.rb:661:in `find_by_sql'
... 19 levels...
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:90:in `run'
    from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.5/lib/active_support/callbacks.rb:276:in `run_callbacks'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1098:in `valid_without_callbacks?'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/callbacks.rb:315:in `valid?'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/validations.rb:1077:in `save_without_dirty'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/dirty.rb:79:in `save_without_transactions'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:229:in `send'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:182:in `transaction'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:196:in `save'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
    from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.5/lib/active_record/transactions.rb:196:in `save'
    from (irb):251
    from :0
JackDanger commented 14 years ago

When you remove the plugin does the error go away?

I can't see how this plugin would affect the exists? method. I'm using Rails 2.3.5 and it's working fine for me. The objects get instantiated and the setter methods (@model.myattr = 'x') never gets called.

Can you check that this code works when you remove the plugin? How about if the plugin is installed but the "attr_immutable" call is commented out?

JackDanger commented 14 years ago

Also: thanks for reporting this :) If this is a bug then it means you're solving a problem I was bound to run into myself one day.

tfe commented 14 years ago

It definitely went away after removing the plugin. I wasn't using attr_immutable, just the validator method.

JackDanger commented 14 years ago

You're absolutely right, I wasn't testing with #exists? and the validator method. I've fixed it, pushed the changes, and released a new gem version.

Thanks for all your help!