我目前正在构建一个rails {5}应用,其中shout
可以是TextShout
或PhotoShout
。在创建一个喊叫时,content_id
没有在params中传递,因此引发了Not Null Value错误。在呼叫的迁移中,我无法找到错误的来源。我有以下文件。
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
答案 0 :(得分:1)
text_shout_content_params
和photo_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
{1}}
Smash Mouth - All Star.mp4
答案 1 :(得分:0)
如果您希望内容具有ID,则必须使用import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.sass']
})
export class AppComponent {
log = 0;
showLog = false;
onShowLog(){
this.showLog = true;
return this.log = this.log + 1;
}
}
而不是create
来创建喊叫。 new
将尝试将记录添加到数据库并分配ID。
使用create
可能也是有益的,如果喊号有无效数据且无法保存,则会引发错误。
create!