向数据库中的 2 个表格提交一份表格 - ruby rails
Submit one form to 2 tables in database - ruby on rails
我有 2 个 table,landslides
和 sources
(可能彼此不相关)。我想要一个让用户填写信息然后提交给两个 table 的表格。这是我当前没有 sources
字段的表格:
= form_for :landslide, :url => {:controller => 'landslides', :action => 'create'} do |f|
.form-inputs
%form#landslideForm
.form-group.row
%label.col-sm-2.col-form-label{for: "textinput"}Date
.col-sm-10
= f.date_select :start_date, :class => "form-control"
#Some fields
.form-actions
= f.button :submit, class: "btn btn-lg btn-primary col-sm-offset-5", id: "submitButton"
和参数:
def landslide_params
params.require(:landslide).permit(:start_date, :continent, :country, :location, :landslide_type, :lat, :lng, :mapped, :trigger, :spatial_area, :fatalities, :injuries, :notes)
end
def source_params
params.require(:source).permit(:url, :text, :landslide_id)
end
sources
调用 landslide_id
中还有一列从 table landslides
中获取滑坡 ID。那么当用户提交新的滑坡时,如何获取即将到来的滑坡ID(自动递增,用户无需填写)?
谢谢!
您需要使用 accept_nested_attributes_for
并相应地嵌套您的表单:
(关于应该嵌套在哪个表单中的保留,我使用通过 landslide-form 提交的源的示例。)
在landslide.rb
accept_nested_attributes_for :sources
在你看来(我不知道 haml 但无论如何)
<%= form_for :landslide do |f|%>
<%= f.select :start_date %>
<%= fields_for :sources do |s| %>
<%= s.input :your_column %>
<% end %>
<%= f.button :submit %>
<% end %>
顺便说一句,关于这个已经有很多问题了,它被称为'Nested Forms'
Nested forms in rails - accessing attribute in has_many relation
Rails -- fields_for not working?
fields_for in rails view
HTML 不允许嵌套 <form>
元素,您不能通过表单传递尚未持久化的记录的 ID(因为它没有 ID)。
要在您使用的同一请求中创建嵌套资源 accepts_nested_attributes_for
:
class Landslide
# or has_many
has_one :source
accepts_nested_attributes_for :source
end
class Source
belongs_to :landslide
end
这意味着您可以执行 Landslide.create(source_attributes: { foo: 'bar' })
,它将创建 Landslide
和 Source
记录,并会自动 link 通过 sources.landslide_id
.
要创建表单输入,请使用 fields_for
:
# use convention over configuration
= form_for @landslide do |f|
.form-inputs
.form-group.row
# use the form builder to create labels instead
= f.label :start_date, class: 'col-sm-2 col-form-label'
.col-sm-10
= f.date_select :start_date, class: "form-control"
%fieldset
%legend Source
= f.fields_for :sources do |s|
.form-group.row
= s.label :url, class: 'col-sm-2 col-form-label'
.col-sm-10
= s.text_field :url, class: "form-control"
# ...
class LandslidesController
# ...
def new
@landslide = Landslide.new
# this is needed to seed the form with inputs for source
@landslide.source.new
end
def create
@landslide = Landslide.new(landslide_params)
if @landslide.save
redirect_to @landslide
else
@landslide.source.new unless @landslide.source.any?
render :new
end
end
private
def landslide_params
params.require(:landslide).permit(
:start_date, :continent, :country,
:location, :landslide_type,
:lat, :lng, :mapped, :trigger, :spatial_area,
:fatalities, :injuries, :notes,
source_attributes: [ :url, :text ]
)
end
end
我有 2 个 table,landslides
和 sources
(可能彼此不相关)。我想要一个让用户填写信息然后提交给两个 table 的表格。这是我当前没有 sources
字段的表格:
= form_for :landslide, :url => {:controller => 'landslides', :action => 'create'} do |f|
.form-inputs
%form#landslideForm
.form-group.row
%label.col-sm-2.col-form-label{for: "textinput"}Date
.col-sm-10
= f.date_select :start_date, :class => "form-control"
#Some fields
.form-actions
= f.button :submit, class: "btn btn-lg btn-primary col-sm-offset-5", id: "submitButton"
和参数:
def landslide_params
params.require(:landslide).permit(:start_date, :continent, :country, :location, :landslide_type, :lat, :lng, :mapped, :trigger, :spatial_area, :fatalities, :injuries, :notes)
end
def source_params
params.require(:source).permit(:url, :text, :landslide_id)
end
sources
调用 landslide_id
中还有一列从 table landslides
中获取滑坡 ID。那么当用户提交新的滑坡时,如何获取即将到来的滑坡ID(自动递增,用户无需填写)?
谢谢!
您需要使用 accept_nested_attributes_for
并相应地嵌套您的表单:
(关于应该嵌套在哪个表单中的保留,我使用通过 landslide-form 提交的源的示例。)
在landslide.rb
accept_nested_attributes_for :sources
在你看来(我不知道 haml 但无论如何)
<%= form_for :landslide do |f|%>
<%= f.select :start_date %>
<%= fields_for :sources do |s| %>
<%= s.input :your_column %>
<% end %>
<%= f.button :submit %>
<% end %>
顺便说一句,关于这个已经有很多问题了,它被称为'Nested Forms'
Nested forms in rails - accessing attribute in has_many relation
Rails -- fields_for not working?
fields_for in rails view
HTML 不允许嵌套 <form>
元素,您不能通过表单传递尚未持久化的记录的 ID(因为它没有 ID)。
要在您使用的同一请求中创建嵌套资源 accepts_nested_attributes_for
:
class Landslide
# or has_many
has_one :source
accepts_nested_attributes_for :source
end
class Source
belongs_to :landslide
end
这意味着您可以执行 Landslide.create(source_attributes: { foo: 'bar' })
,它将创建 Landslide
和 Source
记录,并会自动 link 通过 sources.landslide_id
.
要创建表单输入,请使用 fields_for
:
# use convention over configuration
= form_for @landslide do |f|
.form-inputs
.form-group.row
# use the form builder to create labels instead
= f.label :start_date, class: 'col-sm-2 col-form-label'
.col-sm-10
= f.date_select :start_date, class: "form-control"
%fieldset
%legend Source
= f.fields_for :sources do |s|
.form-group.row
= s.label :url, class: 'col-sm-2 col-form-label'
.col-sm-10
= s.text_field :url, class: "form-control"
# ...
class LandslidesController
# ...
def new
@landslide = Landslide.new
# this is needed to seed the form with inputs for source
@landslide.source.new
end
def create
@landslide = Landslide.new(landslide_params)
if @landslide.save
redirect_to @landslide
else
@landslide.source.new unless @landslide.source.any?
render :new
end
end
private
def landslide_params
params.require(:landslide).permit(
:start_date, :continent, :country,
:location, :landslide_type,
:lat, :lng, :mapped, :trigger, :spatial_area,
:fatalities, :injuries, :notes,
source_attributes: [ :url, :text ]
)
end
end