rails 3.2 ActiveModel::MissingAttributeError #2

antonovga opened this Issue Jan 23, 2012 · 6 comments

2 participants


Hi, after upgrading to rails 3.2 there is an error while trying to update attr_taggable field
ActiveModel::MissingAttributeError: can't write unknown attribute name_of_taggable_field
it points to "write_attribute(context, list)" in taggable.rb

ActiveModel::MissingAttributeError: can't write unknown attribute `elements'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.0/lib/active_record/attribute_methods/write.rb:34:in `write_attribute'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.0/lib/active_record/attribute_methods/dirty.rb:67:in `write_attribute'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/rocket_tag-0.0.4/lib/rocket_tag/taggable.rb:212:in `block (3 levels) in attr_taggable'
from (irb):5
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands/console.rb:47:in `start'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands/console.rb:8:in `start'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'

After downgrading to rails 3.1.3 everything worked fine again.


Can you please provide the context of the error message and not just the error message. There is an extensive test suite. Perhapps you can try the test suite or extend it under Rails 3.2 for your specific error.


If I undertand correctly what context is:
rails new test_rocket;cd ./test_rocket; echo "gem 'rocket_tag'" >> ./Gemfile; bundle install; rails g rocket_tag:migration;rails g model Spot name:string; rake db:migrate + adding attr_taggable
class Spot < ActiveRecord::Base
then rails console and
s = Spot.create name: "abc"
s.tag = "def"
as result

ActiveModel::MissingAttributeError: can't write unknown attribute tag'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.0/lib/active_record/attribute_methods/write.rb:34:in
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.2.0/lib/active_record/attribute_methods/dirty.rb:67:in write_attribute'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/rocket_tag-0.0.4/lib/rocket_tag/taggable.rb:211:in
block (3 levels) in attr_taggable'
from (irb):6
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands/console.rb:47:in start'
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands/console.rb:8:in
from /home/grg/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.0/lib/rails/commands.rb:41:in <top (required)>'
from script/rails:6:in
from script/rails:6:in `


tests didn't run until I update rspecc ccore to 2.4.0, all tests passing, I'm new to rspec, will try to write some test.

ruby 1.9.3, rails 3.2


You mean that the test passes in rails 3.2. That sux :) Must be something other than you think it is.


I'm sorry, I'm new to rspec, all test passed with active_record 3.1.0
With active_record 3.2.0 all tests failed, on every assignment with same error "ActiveModel::MissingAttributeError: can't write unknown attribute attr_name", where attr_name is tag field name


Ok I've upgrade my sandbox with Gemfile

source "http://rubygems.org"
# Add dependencies required to use your gem here.
# Example:
#   gem "activesupport", ">= 2.3.5"
gem "activerecord", ">= 3.2.0"
gem "squeel", :require => false

# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
  gem "rspec", "~> 2.3.0"
  gem "yard", "~> 0.6.0"
  gem "bundler", "~> 1.0.0"
  gem "jeweler", "~> 1.6.4"
  #gem "rcov", ">= 0"
  gem 'sqlite3'

and I see the same error. I will take a look into it.


I think I know what is going on. Rails 3.2 seems to have changed the way constructors handle parameters.

      m = TaggableModel.new :skills => %q%hello, is it me, you are looking for, cat%

There is no database field called :skills but there is a generated method

216             define_method "#{context}=" do |list|
217               list = Manager.parse_tags list
219               # Ensure the tags are loaded
220               cache_tags
221               write_attribute(context, list)
223               (@tag_dirty ||= Set.new) << context
226             end

so there should be a method of assignment. But according to the active record docs

new(attributes = nil) {|self if block_given?| ...}

New objects can be instantiated as either empty (pass no construction parameter) or 
pre-set with attributes but not yet saved (pass a hash with key names matching the 
associated table column names). In both instances, valid attribute keys are determined 
by the column names of the associated table — hence you can‘t have attributes that
aren‘t part of the table columns.

so I guess I was just lucky to get away with in previous versions and the API has been tightened up.

And here is a Rails issue tracking the problem which other people have come across


@bradphelan bradphelan added a commit that referenced this issue Jan 24, 2012
@bradphelan Closes issue #2
Makes compatible with ActiveRecord 3.2
@bradphelan bradphelan closed this Jan 24, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment