如何解决ActiveRecord::NotNullViolation in ReviewsController#create
在 Rails 中收到此错误: PG::NotNullViolation:错误:“reviewer_id”列中的空值违反非空约束详细信息:失败的行包含 (26,2222,8,null,2021-01-30 19:26:03.354983,2021-01-) 30 19:26:03.354983)。
此应用试图让用户给其他用户评价。 我是新手,所以错误可能很明显,但对于未经训练的人来说不会。经过数小时的研究,这是我最后的选择。 我很感激帮助解决这个问题。上帝保佑。
routes.rb
resources :users do
resources :reviews,only: [ :new,:create ]
end
reviews_controller.rb
def create
@review = Review.new(review_params)
@review.user_id = current_user.id
if @review.save
redirect_to user_path(current_user),notice: 'Review added!'
else
render :new
end
end
private
def review_params
params.require(:review).permit(:rating,:content)
end
schema.rb
create_table "reviews",force: :cascade do |t|
t.text "content"
t.integer "rating"
t.bigint "user_id",null: false
t.bigint "reviewer_id",null: false
t.datetime "created_at",precision: 6,null: false
t.datetime "updated_at",null: false
t.index ["reviewer_id"],name: "index_reviews_on_reviewer_id"
t.index ["user_id"],name: "index_reviews_on_user_id"
end
create_table "users",force: :cascade do |t|
t.string "email",default: "",null: false
t.string "encrypted_password",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.inet "current_sign_in_ip"
t.inet "last_sign_in_ip"
t.datetime "created_at",null: false
t.string "username"
t.index ["email"],name: "index_users_on_email",unique: true
t.index ["reset_password_token"],name: "index_users_on_reset_password_token",unique: true
t.index ["username"],name: "index_users_on_username",unique: true
end
add_foreign_key "offers","games"
add_foreign_key "offers","users"
add_foreign_key "rentals","offers"
add_foreign_key "rentals","users"
add_foreign_key "reviews","users",column: "reviewer_id"
user.rb
has_many :reviews,dependent: :destroy
has_many :given_reviews,source: :reviews,foreign_key: :reviewer_id
has_many :received_reviews,foreign_key: :user_id
review.rb
belongs_to :user
validates :content,presence: true
validates :rating,presence: true
解决方法
您有一个关于 Review 的数据库约束,对于 reviewer_id 字段,在您的架构中定义:
t.bigint "reviewer_id",null: false
在您的 controller#create
操作中,您定义了一个 user_id
,但我没有看到您在哪里传递 reviewer_id
或设置它。如果表单中有一个字段,则需要将该参数添加到 review_params
以便它可以从表单传递到控制器操作。或者您需要在 create
操作中定义它,类似于您定义 user_id
的方式。
由于您的评论者是留下评论的人,而用户正在接受评论,我会这样做:
在您留下评论的视图中(我假设这是 User#show
),您正在查看特定用户。您知道这是哪个用户,并且最有可能在该视图中将其定义为 @user
,因此您最有可能在表单中使用 <%= hidden_field_tag :user_id,@user.id %>
进行评论。这会将 user_id
传递给参数中的 Reviews#create 操作。您还需要将 user_id
添加到 review_params
以便可以在 #create
操作中访问它。
然后在您的 Reviews#create
操作中,分配 @review.reviewer_id = current_user.id
。 @review.user_id
将在您调用 Review.create(review_params)
时分配,假设您已按照上述建议将其添加到表单和 review_params
。
尝试在 create
操作中添加断点并查看从审核表单发送的 params 对象,这可能有助于您了解发生了什么。
典型的 Rails 实践也是使用模型验证。这样,您就会在请求到达数据库之前收到应用错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。