使用 nested_attributes 形式创建新模型记录或查看它是否已存在 - Rails 4
Create new model record or see if it already exists using nested_attributes form - Rails 4
我正在使用 has_nested_attributes_for 创建两个不同模型(父模型和子模型)的两个记录。当前使用 has_nested_attributes,我在父级上的 new.html.erb 表单成功创建了父级和子级并将它们关联在一起。然而,子模型的父记录可以have_many关联到它。因此,从新表单中,我需要能够输入一个 url 属性(父模型上的一列),如果 url 已经存在......它应该作为一个已经存在的父项弹出(如果需要 jquery,我可能会为此使用 'rails-jquery-autocomplete' gem)...从而在表单上设置现有的父 ID。但是,如果它尚不存在,则该表单应该像当前成功发生的那样创建一个新的父记录和子记录。
我需要如何更改我的控制器和视图才能完成这种条件嵌套表单?谢谢,
父控制器:
class StoriesController < ApplicationController
def new
@story = Story.new
video = @story.videos.build
end
def create
@story = Story.new(story_params)
if @story.save
flash[:success] = "Your story video has been created."
redirect_to current_narrator
else
flash[:alert] = "Your story or video could not be saved. Please include all fields."
render 'new'
end
end
private
def story_params
params.require(:story).permit(:headline, :url, videos_attributes: [
:imovie,
:director_id
],)
end
end
App/Views/Stories new.html.erb:
<!-- New Story Nested Form -->
<% provide(:title, 'New Story') %>
<div class="container s-in-reg">
<div class="authform">
<h1>New Story</h1>
<%= form_for @story do |f| %>
<div class="field">
<%= f.label :headline %><br />
<%= f.text_field :headline %>
</div><br/>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div><br/>
<%= f.fields_for :videos do |builder| %>
<div class="field">
<%= render 'video_fields', f: builder %>
# Video_fields partial contains the nested video fields required
</div>
<% end %>
<%= f.submit "Post this story", class: "btn btn btn-info" %>
<% end %>
</div>
</div>
Story.RB 型号:
has_many :videos
accepts_nested_attributes_for :videos
validates :headline, presence: true
validates :url, presence: true, uniqueness: true
Video.RB 型号:
class Video < ActiveRecord::Base
belongs_to :story
belongs_to :user
has_attached_file :mpeg
has_nested_attributes_for :story
end
所以你想要做的是有一个 child
其中 accepts_nested_attributes_for
一个 parent
.
基本上,最简单的解决方案是如果您已经有一个要与您的 child 相关联的 parent,则传递 parent_id
,或者如果您传递 parent_attributes
只是要创建它。
可能需要您手动检查控制器中的请求参数,并删除未使用的参数以避免混淆。例如,如果你传递 parent_id
你想从返回的散列中完全删除 parent_attributes
,但是如果你传递 parent_id = nil
,那么你想删除 parent_id
并留下 parent_attributes
我正在使用 has_nested_attributes_for 创建两个不同模型(父模型和子模型)的两个记录。当前使用 has_nested_attributes,我在父级上的 new.html.erb 表单成功创建了父级和子级并将它们关联在一起。然而,子模型的父记录可以have_many关联到它。因此,从新表单中,我需要能够输入一个 url 属性(父模型上的一列),如果 url 已经存在......它应该作为一个已经存在的父项弹出(如果需要 jquery,我可能会为此使用 'rails-jquery-autocomplete' gem)...从而在表单上设置现有的父 ID。但是,如果它尚不存在,则该表单应该像当前成功发生的那样创建一个新的父记录和子记录。
我需要如何更改我的控制器和视图才能完成这种条件嵌套表单?谢谢,
父控制器:
class StoriesController < ApplicationController
def new
@story = Story.new
video = @story.videos.build
end
def create
@story = Story.new(story_params)
if @story.save
flash[:success] = "Your story video has been created."
redirect_to current_narrator
else
flash[:alert] = "Your story or video could not be saved. Please include all fields."
render 'new'
end
end
private
def story_params
params.require(:story).permit(:headline, :url, videos_attributes: [
:imovie,
:director_id
],)
end
end
App/Views/Stories new.html.erb:
<!-- New Story Nested Form -->
<% provide(:title, 'New Story') %>
<div class="container s-in-reg">
<div class="authform">
<h1>New Story</h1>
<%= form_for @story do |f| %>
<div class="field">
<%= f.label :headline %><br />
<%= f.text_field :headline %>
</div><br/>
<div class="field">
<%= f.label :url %><br />
<%= f.text_field :url %>
</div><br/>
<%= f.fields_for :videos do |builder| %>
<div class="field">
<%= render 'video_fields', f: builder %>
# Video_fields partial contains the nested video fields required
</div>
<% end %>
<%= f.submit "Post this story", class: "btn btn btn-info" %>
<% end %>
</div>
</div>
Story.RB 型号:
has_many :videos
accepts_nested_attributes_for :videos
validates :headline, presence: true
validates :url, presence: true, uniqueness: true
Video.RB 型号:
class Video < ActiveRecord::Base
belongs_to :story
belongs_to :user
has_attached_file :mpeg
has_nested_attributes_for :story
end
所以你想要做的是有一个 child
其中 accepts_nested_attributes_for
一个 parent
.
基本上,最简单的解决方案是如果您已经有一个要与您的 child 相关联的 parent,则传递 parent_id
,或者如果您传递 parent_attributes
只是要创建它。
可能需要您手动检查控制器中的请求参数,并删除未使用的参数以避免混淆。例如,如果你传递 parent_id
你想从返回的散列中完全删除 parent_attributes
,但是如果你传递 parent_id = nil
,那么你想删除 parent_id
并留下 parent_attributes