Ruby on rails ActiveRecord::NotNullViolation(PG::NotNullViolation:ERROR:column“content”id“中的null值违反了NOTNULL约束

Ruby on rails ActiveRecord::NotNullViolation(PG::NotNullViolation:ERROR:column“content”id“中的null值违反了NOTNULL约束,ruby-on-rails,ruby,polymorphic-associations,Ruby On Rails,Ruby,Polymorphic Associations,我目前正在构建一个rails 5应用程序,其中shout可以是TextShout或PhotoShout。创建一个shout时,content\u id没有被传递到参数中,因此引发了一个非空值错误。在shout的迁移过程中,我找不到错误的来源。我有以下文件 show.html.erb <%= form_for @shout do |form| %> <%= form.hidden_field :content_type, value: "TextShout" %> &l

我目前正在构建一个rails 5应用程序,其中
shout
可以是
TextShout
PhotoShout
。创建一个shout时,
content\u id
没有被传递到参数中,因此引发了一个非空值错误。在shout的迁移过程中,我找不到错误的来源。我有以下文件

show.html.erb

<%= form_for @shout do |form| %>
<%= form.hidden_field :content_type, value: "TextShout" %>
  <%= form.fields_for :content do |content_form| %>
    <%= content_form.text_field :body, placeholder: "shout here!", required: true %>
    <%= content_form.submit "Shout!" %>
    <% end %>
<% end %>

<%= form_for @shout do |form| %>
<%= form.hidden_field :content_type, value: "PhotoShout" %>
  <%= form.fields_for :content do |content_form| %>
    <%= content_form.file_field :image, required: true %>
    <%= content_form.submit "Shout!" %>
    <% end %>
<% end %>

<%= render @shouts %>

迁移/_make_shouts_polymorphic.rb

class MakeShoutsPolymorphic < ActiveRecord::Migration[5.1]
  class Shout < ApplicationRecord
    belongs_to :content, polymorphic: true
  end
  class TextShout < ApplicationRecord; end
  def change
    change_table(:shouts) do |t|
      t.string :content_type
      t.integer :content_id
      t.index [:content_type, :content_id]
    end

    reversible do |dir|
      Shout.reset_column_information
      Shout.find_each do |shout|
        dir.up do
          text_shout = TextShout.create(body: shout.body)
          shout.update(content_id: text_shout.id, content_type: "TextShout")
        end
        dir.down do
          shout.update(body: shout.content.body)
          shout.content.destroy 
        end
      end
    end

    remove_column :shouts, :body, :string
  end
end
类MakeShoutsPolymorphic houts_controller.rb

class ShoutsController < ApplicationController

  def show
    @shout = Shout.find(params[:id])
  end

  def create
    shout = current_user.shouts.create(shout_params)
    redirect_to root_path, redirect_options_for(shout)
  end

  private

  def shout_params
    { content: content_from_params }
  end

  def content_from_params
    case params[:shout][:content_type]
    when "TextShout" then TextShout.new(text_shout_content_params)
    when "PhotoShout" then PhotoShout.new(photo_shout_content_params)
    end
  end

  def text_shout_content_params
    params.require(:shout).require(:content).permit(:body)
  end

  def photo_shout_content_params
    params.require(:shout).require(:content).permit(:image)
  end

  def redirect_options_for(shout)
    if shout.persisted?
      {notice: "Shouted Successfully"}
    else
      {alert: "Could not shout"}
    end
  end
end
class shoutcontroller
无论是
text\u shout\u content\u params
还是
photo\u shout\u content\u params
都不允许使用
content\u id
,但看起来您正试图(或至少您应该打算)在
content\u中从参数创建一个

def content_from_params
  case params[:shout][:content_type]
    when "TextShout" 
      shout = TextShout.new(text_shout_content_params)
    when "PhotoShout"
      shout = PhotoShout.new(photo_shout_content_params)
  end
  shout.save!
  params[:shout][:content_id] = shout.id 
  params[:shout]
end

如果您希望内容具有id,则必须使用
create
而不是
new
创建呼喊
create
将尝试向数据库添加记录并分配id

使用
create!
也可能有益,如果呼喊包含无效数据且无法保存,则会引发错误

def content_from_params
  case params[:shout][:content_type]
  when "TextShout" then TextShout.create(text_shout_content_params)
  when "PhotoShout" then PhotoShout.create(photo_shout_content_params)
  end
end