首页 > 解决方案 > 在 Rails 中迁移后保存到数据库不起作用

问题描述

我想用 Rails 创建一个 todo 应用程序,我决定添加一个登录功能。我添加了 users 表和两个迁移:一个将列“user_id”添加到 todo 表,另一个使“user_id”不为空。这意味着为了创建一个待办事项,它必须有一个用户 ID。创建列:

    class AddColumnOnCreateTodos < ActiveRecord::Migration[6.1]
  def change
    add_column(:todos, :user_id, :integer)
  end
end

更改为不为空:

   class ChangeColumnOnCreateTodos < ActiveRecord::Migration[6.1]
      def change
        change_column_null(:todos, :user_id, false)
      end
    end

现在,一切正常。我可以访问当前登录的用户,并且该列添加了非空约束。但是,不知何故,我的 todo_controller 中的 create 函数不起作用。每次我想创建一个新的 todo 时,SQL 语句如下:

INSERT INTO "todos" ("title", "description", "created_at", "updated_at") VALUES (?, ?, ?, ?) 

我的 todo_controller 的 create 方法如下所示:

 def create
    @todo = Todo.new(todo_params)
    if @todo.save
      redirect_to to_dos_path
    else
      render :new
    end
  end

而 todo_params 是这样的:

private
  def todo_params
    user = Current.user.id
    puts user
    params.require(:todo).permit(:title, :description, user)
  end

它不知何故不知道添加了 user_id 列。我是rails新手,所以我错过了什么?我确实重置了整个数据库,进行了回滚、迁移、rake db:reset db:migrate 等。我不知道为什么它不起作用。

标签: ruby-on-railsdatabase-migration

解决方案


您添加了一个非空约束,但您正在创建没有用户外键的 Todo,这就是它不保存的原因。

您需要通过关联创建 Todo,但您需要首先在您的用户模型中拥有此关联:

has_many :todos

这将允许您通过关联创建待办事项

user = Current.user.id
todo = user.todos.create(todo_params)

关于 todo_params 中的 permit 方法的另一个注意事项,permit 用于允许您的请求附带的参数用于创建或更新记录,只有 permit 函数中的属性将用于创建您的 todo。所以添加userpermit 并不会真正改变任何东西,因为这个值最初并不存在于请求参数中。

另一种解决方案是将允许的参数与 user_id 合并,这样它就可以用于创建待办事项

def todo_params
  user = Current.user.id
  params.require(:todo).permit(:title, :description).merge(user_id: user.id)
end

推荐阅读