【问题标题】:ActiveModel::MissingAttributeError (can't write unknown attribute `user_id`)ActiveModel::MissingAttributeError(无法写入未知属性 `user_id`)
【发布时间】:2018-01-03 01:06:43
【问题描述】:

部署应用程序时,我的 cmets 出现问题。本地一切正常。 heroku 的日志说:

ActiveModel::MissingAttributeError (can't write unknown attribute `user_id`):
2018-01-02T15:52:43.461794+00:00 app[web.1]: [79cd7190-e2d9-4dd0-bf71-
709552e5c6e5] app/controllers/comments_controller.rb:15:in `create'

我不知道发生了什么错误。也许是一些数据库的东西?

我的评论控制器

class CommentsController < ApplicationController

def create 
    @post =Post.find(params[:post_id])
    @comment =@post.comments.create(params[:comment].permit(:name, :body).merge(user: current_user))
    redirect_to post_path(@post)
end


def destroy 

    @post = Post.find(params[:post_id])
    @comment= @post.comments.find(params[:id])
    if current_user.id == @comment.user_id 
        @comment.destroy
    end
    redirect_to post_path(@post)
end
end

我的模型

class User < ApplicationRecord
 has_many :posts

 devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable
end

class Post < ApplicationRecord
  belongs_to :user, optional: true
  has_many :comments, dependent: :destroy

  validates :title, presence: true, length: {minimum: 5}
  validates :body, presence: true

end

class Comment < ApplicationRecord
 belongs_to :post
 belongs_to :user
end

我的迁移文件

class CreateComments < ActiveRecord::Migration[5.1]
 def change
 create_table :comments do |t|
   t.string :name
   t.text :body
   t.references :post, index: true

   t.timestamps
 end
 end
end

如果您需要更多代码或有任何想法,请告诉我

编辑:如果我添加一个 user_id 列,我会得到一个 SQLite3::SQLException: duplicate column name: user_id: ALTER TABLE "comments" ADD "user_id" integer 错误

我的 schema.rb

`create_table "comments", force: :cascade do |t|
t.string "name"
t.text "body"
t.integer "post_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.index ["post_id"], name: "index_comments_on_post_id"
end

create_table "posts", force: :cascade do |t|
t.string "title"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "image_file_name"
t.string "image_content_type"
t.integer "image_file_size"
t.datetime "image_updated_at"
t.string "theme"
t.integer "user_id"
end

create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

【问题讨论】:

  • 那么您仍然收到错误消息吗?
  • 是的 im still getting this error, i ran heroku run rake db:migrate` 但仍然可以,我在 heroku 上的 schema.rb 是不同的吗?我的意思是它一定与它有关

标签: ruby-on-rails heroku


【解决方案1】:

您需要将user_id 列添加到您的comments 表中。 belongs_to 需要这个。您还需要一个 post_id 列和 user_id 用于您的 posts 表。

可以自定义列名,但惯例是使用格式parent_table_id

这是来自docs的关键引述:

关联是使用宏式调用实现的,因此您可以 以声明方式向您的模型添加功能。例如,通过声明 一个模型属于另一个模型,您指示 Rails 维护 Primary Key - 两者实例之间的外键信息 模型,并且您还会获得许多实用方法添加到您的 型号。

这意味着,例如,如果您的第一个用户的 id 为 1,那么他们所有的 cmets 和帖子的 user_id 值将是 1,这会实际将记录绑定在一起。

这是一个包含相关行的示例迁移:

def change 
  create_table :comments do |t|
    ...
    t.belongs_to :user, index: true
    ...
  end
end

这有意义吗?如果您有任何问题,请告诉我,我可以根据需要更新:)

【讨论】:

  • 看起来你已经有了comments@minennick 的那一列(这意味着它在这张桌子上应该不是问题)。尝试运行posts 的迁移,看看是否能解决问题?此外,如果您可以从schema.rb 发布相关数据(或自己查看那里),我们可以看到您缺少列的位置。
【解决方案2】:

你需要添加user_id

创建迁移

rails g migration AddUserIdToComment user:references

那就做吧

rake db:migrate

你应该没事的。

【讨论】:

    【解决方案3】:

    您的迁移丢失了

    t.references :user, index: true
    

    所以你需要在 cmets 表中添加 user_id 列

    更新:您似乎遇到了一些迁移问题。我建议您检查 rake db:migrate:status 评论并寻找任何向下迁移。一切就绪后,只需运行 rake db:migrate:down VERSION='VERSION_NUMBER_HERE' 并将您的用户 t.references :user, index: true 添加到同一个迁移并迁移。

    PS:当且仅当您没有推送它时,才更改现有迁移。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      相关资源
      最近更新 更多