简体   繁体   English

在 Rails 中,如何在 View 中构建散列数组以传递给控制器​​?

[英]In Rails, how would you build an array of hashes in the View to pass to the controller?

I'm building a platform that let's user create Projects.我正在构建一个让用户创建项目的平台。 Each Project may have different Roles to be covered, and each Role may have different Requirements that the user applying to it has to meet (a Requirement is a pair of Technology and Level objects).每个项目可能有不同的角色需要覆盖,每个角色可能有不同的需求,用户申请它必须满足(需求是一对技术和级别对象)。

As of now, I have something like this:截至目前,我有这样的事情:

<%= simple_form_for([ @project, @role ], remote: true) do |f| %>
   <%= simple_fields_for :requirement do |ff| %>
      <%= ff.input :technology_id, collection: Technology.all, label:false, prompt: "Tecnología" %>
      <%= ff.input :level_id, collection: Level.all, label:false, prompt: "Nivel" %>
   <% end %>

   <%= f.input :name, label:false, placeholder: "Nombre del rol" %>
   <%= f.input :description, label:false, placeholder: "Descripción" %>
   <%= f.submit "Add role", class: "btn btn-primary" %>
<% end %>

However, that approach is not convenient because it will only let me create 1 Requirement (Tech and Level pair) for that Role.但是,这种方法并不方便,因为它只会让我为该角色创建 1 个要求(技术和级别对)。

How could I let the user create many different Requirements for that Role at once?我怎样才能让用户一次为该角色创建许多不同的需求? I was thinking of building an array of hashes and passing it to the controller so I could then iterate over it.我正在考虑构建一个哈希数组并将其传递给控制器​​,以便我可以对其进行迭代。 Something like:就像是:

requirements = [{technology: "Ruby", level: "Junior"}, {technology: "Rails", level: "Junior"}..]

However, I don't know if that would be the way to do it, and if so if that can be done with simple_form.但是,我不知道这样做是否可行,如果可以,是否可以使用 simple_form 来完成。 Any insight would be appreciated.任何见解将不胜感激。

You don't need to do any silly shenanigans here.你不需要在这里做任何愚蠢的恶作剧。 Just need to change the association to a one-to-many:只需要将关联改为一对多:

class Role < ApplicationRecord
  has_many :requirements
  accepts_nested_attributes_for :requirements
end

class Requirement < ApplicationRecord
  belongs_to :role
  belongs_to :level
  belongs_to :technology
end
<%= simple_form_for([ @project, @role ], remote: true) do |f| %>
   <%= simple_fields_for :requirements do |ff| %>
      <%= ff.input :technology_id, collection: Technology.all, label:false, prompt: "Tecnología" %>
      <%= ff.input :level_id, collection: Level.all, label:false, prompt: "Nivel" %>
   <% end %>
   ...
<% end %>

You then need to seed the association in the controller in order for the inputs to show up:然后,您需要在控制器中设置关联以显示输入:

def new
  @role = Role.new do |r|
    5.times { r.requirements.new }
  end
end

You can whitelist an array of nested attributes by passing an array of symbols corresponding to the attributes you want to permit:您可以通过传递与您要允许的属性相对应的符号数组来将嵌套属性数组列入白名单:

def role_params
  params.require(:role)
        .permit(
           :name, :description,
           requirements_attributes: [
             :id, :_destroy, :technology_id, :level_id
           ]
         )
end

You don't need to loop through anything.你不需要遍历任何东西。 accepts_nested_attributes_for :requirements creates a requirements_attributes= setter that takes care of it all for you. accepts_nested_attributes_for :requirements创建一个requirements_attributes= setter 来为你处理这一切。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM