Comments控件中的Create方法无效。轨道

时间:2015-10-03 09:20:07

标签: mysql ruby-on-rails

我知道有关此主题的类似问题,我已经阅读了所有这些问题,并且无法找到明确的解决方案。在我陈述我的问题之前,我将发布所有必需的代码。

模特:

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列,当我尝试迁移时,表示无法创建重复列。可能因为迁移中已存在的用户有外键吗?我能做错什么?

1 个答案:

答案 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之上的:

enter image description here

无论您使用哪种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