ActiveModel::MissingAttributeError: can't write unknown attribute 'product_id' when using has_many Assosiacion with Spree

StackOverflow https://stackoverflow.com/questions/23367999

Question

I'm trying to add Screenshot's model with :belongs_to Association with SpreeProduct, which has :has_many Association with it.

When I run this:

product = Spree::Product.create :name => 'Test', :price => 100, :description => 'description', available_on: Time.now, shipping_category_id: 'default'
product.screenshots << Screenshot.create(:attachment => open('SOME_IMAGE_URL'))

I get "ActiveModel::MissingAttributeError":

/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/attribute_methods/write.rb:47:in `write_attribute'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/attribute_methods/dirty.rb:70:in `write_attribute'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/attribute_methods.rb:358:in `[]='
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/association.rb:204:in `block in set_owner_attributes'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/association.rb:204:in `each'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/association.rb:204:in `set_owner_attributes'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/has_many_association.rb:34:in `insert_record'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:523:in `block (2 levels) in concat_records'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:367:in `add_to_target'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:522:in `block in concat_records'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:520:in `each'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:520:in `concat_records'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:137:in `block in concat'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:152:in `block in transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/connection_adapters/abstract/database_statements.rb:221:in `within_new_transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/transactions.rb:209:in `transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:151:in `transaction'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_association.rb:137:in `concat'
/Users/maksim/.rvm/gems/ruby-2.0.0-p451@rails_4_0/gems/activerecord-4.0.4/lib/active_record/associations/collection_proxy.rb:943:in `<<'
/Users/maksim/Workspace/gamewanted/lib/tasks/screenshots.rake:8:in `block (2 levels) in <top (required)>'

Here is how Screenshot model looks like.

class Screenshot < Spree::Image
  belongs_to :product
end

And this is SpreeProduct model override.

Spree::Product.class_eval do
  has_attached_file :preview_image // preview images work
  has_many :screenshots
end

Also here is migration file.

class CreateScreenshots < ActiveRecord::Migration
  def change
    create_table :screenshots do |t|
      t.references :product, index: true
      t.timestamps
    end 
  end
end

I have also checked if screenshots table really has product_id column:

   Column   |            Type             |    
------------+-----------------------------+
 id         | integer                     | 
 created_at | timestamp without time zone |                                                          
 updated_at | timestamp without time zone |                                                          
 product_id | integer                     |                                                          
Was it helpful?

Solution

Ok, thank you, everyone. I solved it by simply inheriting Screenshot directly from ActiveRecord::Base, not from Spree::Image.

OTHER TIPS

Maybe it should be something with class_name option:

belongs_to :product, :class_name => 'Spree::Product'

I believe this is an issue with your Screenshot class;

belongs_to :spree_product

will look for spree_product_id and not product_id. If you add a foreign key constraint in your belongs to, this might solve your problem.

belongs_to :spree_product, :foreign_key => "product_id"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top