簡體   English   中英

ActiveRecord :: NotNullViolation(PG :: NotNullViolation:錯誤:“ content_id”列中的空值違反了非空約束

[英]ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column “content_id” violates not-null constraint

我目前正在構建Rails 5應用程序,其中的shout可以是TextShoutPhotoShout 創建喊叫時,不會在參數中傳遞content_id ,因此會引發“非空值”錯誤。 在大喊大叫的遷移中,我找不到錯誤的出處。 我有以下文件。

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

shouts_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

無論text_shout_content_paramsphoto_shout_content_params都不允許content_id ,但似乎您正在嘗試(或至少應該打算)在content_from_params創建一個

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!可能也有好處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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM