【问题标题】:ActiveModel::MissingAttributeError: can't write unknown attribute 'product_id' when using has_many Assosiacion with SpreeActiveModel::MissingAttributeError: can't write unknown attribute 'product_id' when using has_many Assosiacion with Spree
【发布时间】:2014-04-29 14:45:59
【问题描述】:

我正在尝试添加带有 :belongs_to 与 SpreeProduct 关联的屏幕截图模型,该模型具有 :has_many 与之关联。

当我运行这个时:

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'))

我得到“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)>'

这是截图模型的样子。

class Screenshot < Spree::Image
  belongs_to :product
end

这是 SpreeProduct 模型覆盖。

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

这里还有迁移文件。

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

我还检查了 screenshots 表是否真的有 product_id 列:

   Column   |            Type             |    
------------+-----------------------------+
 id         | integer                     | 
 created_at | timestamp without time zone |                                                          
 updated_at | timestamp without time zone |                                                          
 product_id | integer                     |                                                          

【问题讨论】:

    标签: ruby-on-rails ruby activerecord spree


    【解决方案1】:

    好的,谢谢大家。我通过简单地直接从ActiveRecord::Base 继承截图来解决它,而不是从Spree::Image

    【讨论】:

      【解决方案2】:

      也许它应该是带有 class_name 选项的东西:

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

      【讨论】:

      • 不,这没有帮助。
      【解决方案3】:

      我认为这是您的 Screenshot 课程的问题;

      belongs_to :spree_product

      将寻找 spree_product_id 而不是 product_id。如果你在你的所属中添加一个外键约束,这可能会解决你的问题。

      belongs_to :spree_product, :foreign_key =&gt; "product_id"

      【讨论】:

      • 但是我会在抱怨缺少 spree_product_id 时出错。我也尝试添加foreign_key,但没有任何改变。
      • 有趣。您是否尝试在将其与产品关联之前创建屏幕截图?如果创建屏幕截图失败或与产品的关联失败,这将允许您进行绑定。我的感觉是您的 Screenshot.create 在将其与产品关联之前需要在创建中使用 product_id。 Screenshot.create(:attachment =&gt; open('SOME_IMAGE_URL'), :product_id =&gt; product.id)
      • 我尝试在创建屏幕截图后添加puts "screenshot added",通过在输出中看到它,我认为它已成功创建。
      • 我还为原始问题添加了完整输出,因此您可以看到&lt;&lt; operator 上出现错误
      • 我的最后一个想法是,它与模型在每次请求时重新加载以及 class_eval 只加载一次有关。您可以尝试将以下代码添加到您的 .rb 文件中,看看是否能解决问题。 # 加载扩展产品的文件,每次加载模型时config.to_prepare do load 'extend_product.rb' end
      猜你喜欢
      • 2017-03-23
      • 2015-11-20
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多