我知道有关此主题的类似问题,我已经阅读了所有这些问题,并且无法找到明确的解决方案。在我陈述我的问题之前,我将发布所有必需的代码。
模特:
class Comment < ActiveRecord::Base
belongs_to :user
belongs_to :scoreboard
end
class User < ActiveRecord::Base
has_many :scoreboards, dependent: :destroy
has_many :comments, dependent: :destroy
end
class Scoreboard < ActiveRecord::Base
belongs_to :user
has_many :teams, dependent: :destroy
has_many :comments, dependent: :destroy
end
记分板类似于用户可以发表评论的文章页面。
评论的迁移:
class CreateComments < ActiveRecord::Migration
def change
create_table :comments do |t|
t.text :body
t.text :reply
t.references :user, index: true
t.references :scoreboard, index: true
t.timestamps null: false
end
add_foreign_key :comments, :users
add_foreign_key :comments, :scoreboards
end
end
问题在于评论控制器中的创建方法。以下是该方法的代码:
def create
@scoreboard = Scoreboard.find(params[:scoreboard_id])
@comment.user_id = current_user.id
@comment = @scoreboard.comments.build(comment_params)
redirect_to scoreboard_url(@comment.scoreboard_id)
end
current_user方法位于单独文件夹中的帮助程序文件中。 每当我提交表单以获得新评论时,我都会收到以下错误:
undefined method `user_id=' for nil:NilClass
堆栈上的一个问题是注释中需要user_id列,当我尝试迁移时,表示无法创建重复列。可能因为迁移中已存在的用户有外键吗?我能做错什么?
答案 0 :(得分:2)
错误很简单:
@comment.user_id = current_user.id
@comment = @scoreboard.comments.build(comment_params)
你在没有事先定义的情况下调用@comment
。
应该是这样的:
@comment = @scoreboard.comments.build comment_params
@comment.user_id = current_user.id
堆栈上的一个问题表明评论中需要一个user_id列
澄清一下,他们指的是Comment
模型的foreign_key
。
您必须记住,Rails是建立在relational database之上的:
无论您使用哪种SQL,您仍然会以关系方式使用它; Rails添加了ActiveRecord "object relational mapper"。
简单地说,这使得Rails能够使用不同的查询等来调用关联数据。我们没有看到任何技术细节;只有@scoreboard.comments
关联。
在后端,Rails必须计算哪些数据与另一个数据相关。在使用适当的关系数据库结构时,这只能发生 - 包括使用foreign_keys
。
这就是为什么在创建关联对象时必须分配user_id
之类的内容。但是有一个技巧可以让它更简洁:
#app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@scoreboard = Scoreboard.find params[:scoreboard_id]
@comment = @scoreboard.comments.build comment_params
end
private
def comment_params
params.require(:comment).permit(:params).merge(user_id: current_user.id)
end
end