模型的未知属性 'type'

unknown attribute 'type' for Model

我是 运行 rails 的后台工作,负责创建图像并将它们添加到图库中。稍后可以将图像添加到其他画廊,因此这两者之间自然存在 has_many_through 关系。

当作业到达下面几行时,我得到错误:

unknown attribute 'type' for GalleryImages.

我没有使用任何属性 'type' 所以我想问题要么出在我使用 rails 的方式上,要么出在我的想法上。希望你们能帮我解决这个问题。

相关宝石

gem 'rails', '4.2.6'
gem 'sqlite3'
gem 'delayed_job_active_record'
gem 'daemons'

job.rb

class Job < Struct.new(:museum_id)
    def perform
        puts "starting bg job"
        museum = Museum.find(museum_id)
        begin
            gallery = museum.gallery.create(name: 'somename', description: 'some virtual museum',)
        rescue => e
            puts e
        end
        path = '/home/parrot/pic.png'
        puts path
        md5 = Digest::MD5.hexdigest(File.read(path))
        puts md5
        begin
            image = Image.create!(path: path, md5: md5) # create! raises an exception if validation fails
            gallery.images << image
        rescue => e
            puts e.message
            puts e.backtrace.join("\n")
        end
    end
end

gallery_image.rb

class GalleryImage < ActiveRecord::Base
    belongs_to :gallery
    belongs_to :image
end

image.rb

class Image < ActiveRecord::Base
  has_many :gallery_images, :class_name => 'GalleryImage'
  has_many :galleries, through: :gallery_images
  validates :path, :md5, presence: true
  validates :md5, uniqueness: true
end

gallery.rb

class Gallery < ActiveRecord::Base
  belongs_to :museum
  has_many :gallery_images, :class_name => 'GalleryImage'
  has_many :images, through: :gallery_images
end

20160427100528_create_gallery_images 迁移

class CreateGalleryImages < ActiveRecord::Migration
  def change
    create_table :gallery_images, id: false do |t|
      t.belongs_to :gallery, index: true
      t.belongs_to :image, index: true
    end
  end
end

schema.rb

ActiveRecord::Schema.define(version: 20160427100528) do

  create_table "delayed_jobs", force: :cascade do |t|
    t.integer  "priority",   default: 0, null: false
    t.integer  "attempts",   default: 0, null: false
    t.text     "handler",                null: false
    t.text     "last_error"
    t.datetime "run_at"
    t.datetime "locked_at"
    t.datetime "failed_at"
    t.string   "locked_by"
    t.string   "queue"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority"

  create_table "images", force: :cascade do |t|
    t.string   "md5"
    t.string   "path"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "gallery_images", force: :cascade do |t|
    t.integer  "gallery_id"
    t.integer  "image_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  add_index "gallery_images", ["image_id"], name: "index_gallery_images_on_image_id"
  add_index "gallery_images", ["gallery_id"], name: "index_gallery_images_on_gallery_id"

  create_table "galleries", force: :cascade do |t|
    t.integer  "name"
    t.integer  "description"
    t.integer  "museum_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "museum_galleries", force: :cascade do |t|
    t.integer "gallery_id"
    t.integer "museum_id"
  end

  create_table "museums", force: :cascade do |t|
    t.string   "name"
    t.string   "description"
    t.integer  "gallery_id"
    t.datetime "created_at",   null: false
    t.datetime "updated_at",   null: false
  end
end

e.backtrace

/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb:59:in `rescue in _assign_attribute'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb:54:in `_assign_attribute'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb:41:in `block in assign_attributes'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb:35:in `each'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/attribute_assignment.rb:35:in `assign_attributes'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/core.rb:566:in `init_attributes'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/core.rb:281:in `initialize'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb:61:in `new'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/inheritance.rb:61:in `new'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/reflection.rb:141:in `build_association'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/association.rb:250:in `build_record'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:146:in `build'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb:95:in `build_through_record'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb:117:in `save_through_record'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb:66:in `insert_record'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:563:in `block (2 levels) in concat_records'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:408:in `replace_on_target'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:403:in `add_to_target'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:562:in `block in concat_records'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:560:in `each'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:560:in `concat_records'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_association.rb:180:in `concat_records'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb:44:in `concat_records'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:168:in `block in concat'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:183:in `block in transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `block in transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/transaction.rb:184:in `within_new_transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/connection_adapters/abstract/database_statements.rb:213:in `transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/transactions.rb:220:in `transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:182:in `transaction'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_association.rb:168:in `concat'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/has_many_through_association.rb:38:in `concat'
/home/parrot/.gem/ruby/2.2.0/gems/activerecord-4.2.6/lib/active_record/associations/collection_proxy.rb:970:in `<<'
/home/parrot/learn-rails/onlinemuseum/app/jobs/job.rb:24:in `perform'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/backend/base.rb:100:in `block in invoke_job'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `block in initialize'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `execute'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/backend/base.rb:97:in `invoke_job'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:224:in `block (2 levels) in run'
/home/parrot/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:89:in `block in timeout'
/home/parrot/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:99:in `call'
/home/parrot/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/timeout.rb:99:in `timeout'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:224:in `block in run'
/home/parrot/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:223:in `run'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:300:in `block in reserve_and_run_one_job'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `block in initialize'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `execute'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:300:in `reserve_and_run_one_job'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:207:in `block in work_off'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:206:in `times'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:206:in `work_off'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:169:in `block (4 levels) in start'
/home/parrot/.rvm/rubies/ruby-2.2.0/lib/ruby/2.2.0/benchmark.rb:303:in `realtime'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:168:in `block (3 levels) in start'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `block in initialize'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `execute'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:167:in `block (2 levels) in start'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:166:in `loop'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:166:in `block in start'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/plugins/clear_locks.rb:7:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/plugins/clear_locks.rb:7:in `block (2 levels) in <class:ClearLocks>'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:79:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:79:in `block (2 levels) in add'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:61:in `block in initialize'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:79:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:79:in `block in add'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:66:in `execute'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/lifecycle.rb:40:in `run_callbacks'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/worker.rb:165:in `start'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/command.rb:131:in `run'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/command.rb:119:in `block in run_process'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/application.rb:265:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/application.rb:265:in `block in start_proc'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/application.rb:274:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/application.rb:274:in `start_proc'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/application.rb:295:in `start'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/controller.rb:59:in `run'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons.rb:193:in `block in run_proc'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:in `call'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons/cmdline.rb:88:in `catch_exceptions'
/home/parrot/.gem/ruby/2.2.0/gems/daemons-1.2.3/lib/daemons.rb:192:in `run_proc'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/command.rb:117:in `run_process'
/home/parrot/.gem/ruby/2.2.0/gems/delayed_job-4.1.1/lib/delayed/command.rb:93:in `daemonize'
./bin/delayed_job:5:in `<main>'

如果您的 table 名称为 :gallery_images,您的模型应称为 GalleryImage,因此如果:

create_table :gallery_images, id: false do |t|

将模型和文件名重命名为:

app/models/gallery_image.rb:

class GalleryImage < ActiveRecord::Base

或者反之亦然:模型名称 GalleryImages 和 table 名称 :gallery_imageses.

我在一位更有经验的学生的帮助下调查了这个问题,结果发现我的环境出了问题。清理后一切正常。