Ruby on rails 为每个数组项创建新对象

Ruby on rails 为每个数组项创建新对象,ruby-on-rails,ruby,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 5,错误: 未定义方法 “亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业 对于#我认为您不应该为此使用“新”操作,因为您脱离了约定,rails会发生一些事情。我将创建两个新操作:bulk\u new和bulk\u create 添加这些操作的路由: resources :sub_agricultures do collection do get :bulk_new post :bulk_create end end 新的是,当您将一个模

错误:

未定义方法

“亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业亚农业
对于#我认为您不应该为此使用“新”操作,因为您脱离了约定,rails会发生一些事情。我将创建两个新操作:
bulk\u new
bulk\u create

添加这些操作的路由:

resources :sub_agricultures do
  collection do
    get :bulk_new
    post :bulk_create
  end
end
新的是,当您将一个模型传递给带有helper的表单_时,它会尝试从链接资源名称的数组中推断url,这就是为什么您会看到这个奇怪的命名路由

由于rails无法使用该数组生成专有名称,因此您需要自己生成输入名称前缀,例如:

= form_tag bulk_create_sub_categories_path do |form|
  - sub_agricultures.each do |sub_ag|
    - input_name_prefix = "sub_agricultures[#{sub_ag.scorecard_id}]"
    div
      = hidden_field "#{input_name_prefix}[scorecard_id]", sub_ag.scorecard_id
      = label_tag "#{input_name_prefix}[score]", "Score for #{sub_ag.scorecard_id}"
      = number_field_tag "#{input_name_prefix}[score]", sub_ag.score
      # add some errors feedback too
def bulk_create
  @sub_agricultures: []

  # loop through the sub_agricultures params array
  params[:sub_agricultures].each do |_, sub_ag_data|
    sub_ag = SubAgriculture.new(scorecard_id: sub_ag_data[:scorecard_id], score: sub_ag_data[:score])
    @sub_agricultures << sub_ag
  end

  # now I guess you want to validate all of them:
  if @sub_agricultures.all?(&:valid?)
    @sub_agricultures.each(&:save)
    flash[:notice] = "sub agricultures created"
    redirect_to somewhere_path
  else
    flash.now[:error] = "sub agricultures have errors"
    render action: :bulk_new
  end
end
现在,该表单应提交如下参数散列:

{
  sub_agricultures: [
    1: {scorecard_id: 1, score: XX},
    2: {scorecard_id: 2, score: YY},
    etc...
  ]
}
因此,在
bulk\u创建
操作时,您必须执行以下操作:

= form_tag bulk_create_sub_categories_path do |form|
  - sub_agricultures.each do |sub_ag|
    - input_name_prefix = "sub_agricultures[#{sub_ag.scorecard_id}]"
    div
      = hidden_field "#{input_name_prefix}[scorecard_id]", sub_ag.scorecard_id
      = label_tag "#{input_name_prefix}[score]", "Score for #{sub_ag.scorecard_id}"
      = number_field_tag "#{input_name_prefix}[score]", sub_ag.score
      # add some errors feedback too
def bulk_create
  @sub_agricultures: []

  # loop through the sub_agricultures params array
  params[:sub_agricultures].each do |_, sub_ag_data|
    sub_ag = SubAgriculture.new(scorecard_id: sub_ag_data[:scorecard_id], score: sub_ag_data[:score])
    @sub_agricultures << sub_ag
  end

  # now I guess you want to validate all of them:
  if @sub_agricultures.all?(&:valid?)
    @sub_agricultures.each(&:save)
    flash[:notice] = "sub agricultures created"
    redirect_to somewhere_path
  else
    flash.now[:error] = "sub agricultures have errors"
    render action: :bulk_new
  end
end
def bulk\u创建
@亚农业:[]
#在sub_agricultures参数数组中循环
参数[:sub_agricultures]。每个do|uu、sub_ag_数据|
sub_ag=SubAgriculture.new(记分卡id:sub_ag_数据[:记分卡id],分数:sub_ag_数据[:分数])

@sub_agricultures
form_with
的设计目的不是一次创建多个记录。model关键字将传递给polyphic url帮助程序,因此当您传递模型数组时,您将获得嵌套路由:

polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"
Rails通过调用模型实例上的
model\u name.param\u key
将其解析为
blog\u posts\u path

因为你有一整吨的记录,你得到了这条荒谬的路线
sub\u agriculture\u sub\u agriculture\u sub\u agriculture\u sub\u agriculture\u sub\u agricultures\u路径

即使这样做有效,我也怀疑表单生成器是否有效,因为它是为单个记录实例而设计的。不是数组

如果要使用嵌套属性,则需要包装嵌套属性的模型。因此,您需要重新考虑域建模(您可能会做得更好),或者使用类似
的方法手动处理param绑定等

以这种方式处理大量插入实际上比在数组中循环要复杂得多。您必须确保所有记录都有效并已保存(考虑事务),如果记录无效,则处理将其传递回表单的问题。如果可能的话,我会尽量避免。这是为什么它不是Rails惯例的一部分的原因


一个好的替代方法是使用ajax,让用户在不离开页面的情况下一行一行地创建。您可以通过对正常运行的crud控制器的解剖请求来执行此操作。

您的模型关系可以得到改善。一张记分卡(成绩单)将包含许多科目。因此,最好重新设计这两个类之间的关系。

我不会真正信任
。所有的(&:valid?
)。您可能希望将其包装在事务中,并检查是否保存了所有内容。@绝对正确,但由于对象似乎只保存了一个分数值,我认为这非常简单,只需检查所有内容是否有效,但事务确实更能防止错误。@arieljuod谢谢;这无疑让我更接近预期的解决方案。这就是我到目前为止所得到的<“得分”将是“58”的,”2“=>{“2”号,”2“=>{“记分卡”将是“58”的,”2“2”2“=>{“记分卡”将是一个农村农业农业的“子”农业的”码码>{{“1”号码码>{{“1”1.1”码码码>{{“1.1.1.1.1”节节节节节,,{“1.1”得分”号,”2“>{“2.2”号码码将是农村农业农业农业农业农业的子们们们们们们们们的代码““>{”的代码>>{{{{{”号号号号号码码码码码>>>{{{{{{{{{{”号号,3.3.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1.1 6“=>”},“分数”=>“58”}
sub\u agriculties\u controller.rb中@sub\u agriculties[]的一位命名者,尽管我理解这里的担忧,但仍在处理它;在考虑了用户体验之后,请求在ago上有多个条目。其数值数据短;因此,制作一个条目,在另一个条目可用时提交,对眼睛来说太麻烦了。不必如此。如果你只是在后台保存,它可以对用户完全透明。事实上,从用户体验的角度来看,发布一个大表单也不是很好;我可以使用ajax实现Rails方式吗?就像上面的六个记分卡一样,有一个ajax的东西可以无限滚动显示更多的输入吗?在这种情况下,可能会显示四个,然后使用ajax向下滚动以显示另外两个?一个记分卡有很多主题可能会在数据库中加载不必要的“零”。对于所有现有卡(如上图所示),将有一组“0”记录。这些消耗索引和时间。此解决方案仅提供一个记分卡,该记分卡只能包含该特定学生所选的科目。它还为统计数据和学校公告腾出空间。
= form_tag bulk_create_sub_categories_path do |form|
  - sub_agricultures.each do |sub_ag|
    - input_name_prefix = "sub_agricultures[#{sub_ag.scorecard_id}]"
    div
      = hidden_field "#{input_name_prefix}[scorecard_id]", sub_ag.scorecard_id
      = label_tag "#{input_name_prefix}[score]", "Score for #{sub_ag.scorecard_id}"
      = number_field_tag "#{input_name_prefix}[score]", sub_ag.score
      # add some errors feedback too
{
  sub_agricultures: [
    1: {scorecard_id: 1, score: XX},
    2: {scorecard_id: 2, score: YY},
    etc...
  ]
}
def bulk_create
  @sub_agricultures: []

  # loop through the sub_agricultures params array
  params[:sub_agricultures].each do |_, sub_ag_data|
    sub_ag = SubAgriculture.new(scorecard_id: sub_ag_data[:scorecard_id], score: sub_ag_data[:score])
    @sub_agricultures << sub_ag
  end

  # now I guess you want to validate all of them:
  if @sub_agricultures.all?(&:valid?)
    @sub_agricultures.each(&:save)
    flash[:notice] = "sub agricultures created"
    redirect_to somewhere_path
  else
    flash.now[:error] = "sub agricultures have errors"
    render action: :bulk_new
  end
end
polymorphic_url([blog, post]) # => "http://example.com/blogs/1/posts/1"