Ruby on rails ActiveRecord::NotNullViolation(PG::NotNullViolation:ERROR:column“content”id“中的null值违反了NOTNULL约束
我目前正在构建一个rails 5应用程序,其中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
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
类MakeShoutsPolymorphicclass 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