在同一视图中同时创建 has_many belongs_to 关联子模型和父模型
Creating both has_many belongs_to associations child and parents model at same view
所以我有两个模型:
#app/models/diy.rb
class Diy < Activerecord::Base
#schema id | summary | created_at | updated_at
has_many :steps
end
#app/models/step.rb
class Step < ActiveRecord::Base
# schema id | step_content | photo | created_at | updated_at
belongs_to :diy
end
是否有任何方法可以创建一个 diy 数据库行并在同一视图中将其关联到步骤数据库行?
我最接近的是:
<%= form_for(@diy) do |f| %>
<%= f.label :summary %><br>
<%= f.text_field :summary %><br>
<%= f.label :steps %><br>
<%= f.text_field :steps %><br>
<%= f.submit %>
<% end %>
但是使用此代码我没有访问步骤 table 中的任何列。
如果它有助于解决问题,使用此代码我得到 "Steps" 文本字段,其中已经填充了 "Step::ActiveRecord_Associations_CollectionProxy:0x9613ce0"。
class Diy < ActiveRecord::Base
has_many :steps
accepts_nested_attributes_for :steps
end
class Step < ActiveRecord::Base
belongs_to :diy
end
accepts_nested_attributes_for
让 Diy 获取步骤的属性:
Diy.create( steps_attributes: [{ step_content: 'Stir it.' }] )
要创建表单输入,请使用 fields_for
:
<%= form_for(@diy) do |f| %>
<%= f.label :summary %><br>
<%= f.text_field :summary %><br>
<%- # wrapping it in a fieldset element is optional -%>
<fieldset>
<legend>Steps</legend>
<% f.fields_for(:steps) do |step_fields| %>
<%= step_fields.label :step_content %><br>
<%= step_fields.text_field :step_content %><br>
<% end %>
</fieldset>
<%= f.submit %>
<% end %>
它通过 @diy.steps
迭代并为每个创建一个 <textarea name="diy[steps_attributes][][step_content]">
。 step_fields
是一个表单生成器,它的范围是特定的嵌套记录。
请注意,如果 @diy.steps
像新记录一样为 nil,则不会有表单输入。要解决这个问题,您需要播种记录:
class DiysController
# ...
def new
@diy = Diy.new
@diy.steps.new # creates a new step that the user can fill in.
end
def edit
@diy = Diy.find(params[:id])
@diy.steps.new # creates a new step that the user can fill in.
end
end
为避免出现一堆垃圾步骤,您可以使用 reject_if
选项:
class Diy < ActiveRecord::Base
has_many :steps
accepts_nested_attributes_for :steps, reject_if: :all_blank
end
要将控制器中的嵌套属性列入白名单,请使用包含允许属性的数组:
def diy_params
params.require(:diy).permit(:summary, steps_attributes: [:step_content])
end
请阅读:
要添加到 @Max
的答案,您需要使用以下内容:
#app/models/diy.rb
class Diy < Activerecord::Base
#schema id | summary | created_at | updated_at
has_many :steps
accepts_nested_attributes_for :steps
end
#app/controllers/diys_controller.rb
class DiysController < ApplicationController
def new
@diy = Diy.new
@diy.steps.build
end
def create
@diy = Diy.new diy_params
@diy.save
end
private
def diy_params
params.require(:diy).permit(steps_attributes: [:step_content])
end
end
#app/views/diys/new.html.erb
<%= form_for @diy do |f| %>
<%= f.fields_for :steps do |s| %>
<%= s.number_field :step_count %>
<% end %>
<%= f.submit %>
<% end %>
--
如果您只想将新的 Diy
关联到现有的 Step
,您需要填充 step_ids
(collection_singular_ids
) 属性:
#controller
def diy_params
params.require(:diy).permit(step_ids: [])
end
#app/views/diys/new.html.erb
<%= form_for @diy do |f| %>
<%= f.collection_select :step_ids, Step.all, :id, :name %>
<%= f.submit %>
<% end %>
所以我有两个模型:
#app/models/diy.rb
class Diy < Activerecord::Base
#schema id | summary | created_at | updated_at
has_many :steps
end
#app/models/step.rb
class Step < ActiveRecord::Base
# schema id | step_content | photo | created_at | updated_at
belongs_to :diy
end
是否有任何方法可以创建一个 diy 数据库行并在同一视图中将其关联到步骤数据库行?
我最接近的是:
<%= form_for(@diy) do |f| %>
<%= f.label :summary %><br>
<%= f.text_field :summary %><br>
<%= f.label :steps %><br>
<%= f.text_field :steps %><br>
<%= f.submit %>
<% end %>
但是使用此代码我没有访问步骤 table 中的任何列。
如果它有助于解决问题,使用此代码我得到 "Steps" 文本字段,其中已经填充了 "Step::ActiveRecord_Associations_CollectionProxy:0x9613ce0"。
class Diy < ActiveRecord::Base
has_many :steps
accepts_nested_attributes_for :steps
end
class Step < ActiveRecord::Base
belongs_to :diy
end
accepts_nested_attributes_for
让 Diy 获取步骤的属性:
Diy.create( steps_attributes: [{ step_content: 'Stir it.' }] )
要创建表单输入,请使用 fields_for
:
<%= form_for(@diy) do |f| %>
<%= f.label :summary %><br>
<%= f.text_field :summary %><br>
<%- # wrapping it in a fieldset element is optional -%>
<fieldset>
<legend>Steps</legend>
<% f.fields_for(:steps) do |step_fields| %>
<%= step_fields.label :step_content %><br>
<%= step_fields.text_field :step_content %><br>
<% end %>
</fieldset>
<%= f.submit %>
<% end %>
它通过 @diy.steps
迭代并为每个创建一个 <textarea name="diy[steps_attributes][][step_content]">
。 step_fields
是一个表单生成器,它的范围是特定的嵌套记录。
请注意,如果 @diy.steps
像新记录一样为 nil,则不会有表单输入。要解决这个问题,您需要播种记录:
class DiysController
# ...
def new
@diy = Diy.new
@diy.steps.new # creates a new step that the user can fill in.
end
def edit
@diy = Diy.find(params[:id])
@diy.steps.new # creates a new step that the user can fill in.
end
end
为避免出现一堆垃圾步骤,您可以使用 reject_if
选项:
class Diy < ActiveRecord::Base
has_many :steps
accepts_nested_attributes_for :steps, reject_if: :all_blank
end
要将控制器中的嵌套属性列入白名单,请使用包含允许属性的数组:
def diy_params
params.require(:diy).permit(:summary, steps_attributes: [:step_content])
end
请阅读:
要添加到 @Max
的答案,您需要使用以下内容:
#app/models/diy.rb
class Diy < Activerecord::Base
#schema id | summary | created_at | updated_at
has_many :steps
accepts_nested_attributes_for :steps
end
#app/controllers/diys_controller.rb
class DiysController < ApplicationController
def new
@diy = Diy.new
@diy.steps.build
end
def create
@diy = Diy.new diy_params
@diy.save
end
private
def diy_params
params.require(:diy).permit(steps_attributes: [:step_content])
end
end
#app/views/diys/new.html.erb
<%= form_for @diy do |f| %>
<%= f.fields_for :steps do |s| %>
<%= s.number_field :step_count %>
<% end %>
<%= f.submit %>
<% end %>
--
如果您只想将新的 Diy
关联到现有的 Step
,您需要填充 step_ids
(collection_singular_ids
) 属性:
#controller
def diy_params
params.require(:diy).permit(step_ids: [])
end
#app/views/diys/new.html.erb
<%= form_for @diy do |f| %>
<%= f.collection_select :step_ids, Step.all, :id, :name %>
<%= f.submit %>
<% end %>