【问题标题】:Ruby on Rails: Submitting an array in a formRuby on Rails:以表单提交数组
【发布时间】:2011-03-06 14:43:58
【问题描述】:

我有一个具有数组属性的模型。我从表单提交中填充该属性的正确方法是什么?

我知道有一个表单输入,其名称包含括号的字段会从输入中创建一个哈希。我应该把它拿走并在控制器中单步调试它以将它按摩成一个数组吗?

减少抽象的例子:

class Article
  serialize :links, Array
end

links 变量采用 URL 数组的形式,即[["http://www.google.com"], ["http://stackoverflow.com"]]

当我在表单中使用类似以下内容时,它会创建一个哈希:

<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>

生成的哈希如下所示:

"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}

如果我没有在链接名称中包含 url,其他值会相互破坏:

<%= hidden_field_tag "article[links]", :track, :value => url %>

结果如下所示:"links" =&gt; "http://stackoverflow.com"

【问题讨论】:

    标签: ruby-on-rails arrays forms hash


    【解决方案1】:

    如果您的 html 表单的输入字段带有空方括号,那么它们将在控制器的 params 中转换为数组。

    # Eg multiple input fields all with the same name:
    <input type="textbox" name="course[track_codes][]" ...>
    
    # will become the Array 
       params["course"]["track_codes"]
    # with an element for each of the input fields with the same name
    

    添加:

    请注意,rails 助手不是设置为自动执行数组技巧。因此,您可能必须手动创建 name 属性。此外,如果使用 rails 助手,复选框也会有自己的问题,因为复选框助手会创建额外的隐藏字段来处理未选中的情况。

    【讨论】:

    • 如果您关心数组元素被保留的顺序并且想要真正对标准挑剔,那么可能值得一读this question。听起来 HTML 规范暗示,但不是 100% 清楚,应该保留该顺序,但似乎所有浏览器都这样做。
    • html like &lt;input name="course[track_codes][][field1]" multiple /&gt;&lt;input name="course[track_codes][][field2]" multiple /&gt; 会生成参数{course: {track_codes: [{field1: "yourvalue", field2: "yourvalue"},{field1: "yourvalue", field2: "yourvalue"}]}}
    • @FabrizioBertoglio 如果我们要发送多个标签是一个输入字段怎么办?
    【解决方案2】:
    = simple_form_for @article do |f|
      = f.input_field :name, multiple: true
      = f.input_field :name, multiple: true
      = f.submit
    

    【讨论】:

    • 这就是我要找的东西!
    • 请说明这段代码的作用。像这样的答案不是很有帮助。
    • 应更新接受的答案以包含此 multiple: true 更新,这显然是要走的路。
    • f.input :name, input_html: { multiple: true } 可用于输入
    • f.input: name, multiple: true, value: ... 也适用于 Rails 原生 form_for @article do |f|
    【解决方案3】:

    TL;DR 版本的 HTML [] 约定:

    数组:

    <input type="textbox" name="course[track_codes][]", value="a">
    <input type="textbox" name="course[track_codes][]", value="b">
    <input type="textbox" name="course[track_codes][]", value="c">
    

    收到的参数:

    { course: { track_codes: ['a', 'b', 'c'] } }
    

    哈希

    <input type="textbox" name="course[track_codes][x]", value="a">
    <input type="textbox" name="course[track_codes][y]", value="b">
    <input type="textbox" name="course[track_codes][z]", value="c">
    

    收到的参数:

    { course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
    

    【讨论】:

    • 有没有办法使用 simple_form 来生成这些?
    • @FilipeEsperandio f.input "course[track_codes][x]"
    【解决方案4】:

    我还发现,如果像这样传递您的输入助手,您将获得一系列课程,每个课程都有自己的属性。

    # Eg multiple input fields all with the same name:
    <input type="textbox" name="course[][track_codes]" ...>
    
    # will become the Array 
       params["course"]
    
    # where you can get the values of all your attributes like this:
       params["course"].each do |course|
           course["track_codes"]
       end    
    

    【讨论】:

      【解决方案5】:

      我刚刚使用 jquery taginput 设置了一个解决方案:

      http://xoxco.com/projects/code/tagsinput/

      我写了一个自定义的 simple_form 扩展

      # for use with: http://xoxco.com/projects/code/tagsinput/
      
      class TagInput < SimpleForm::Inputs::Base
      
        def input
          @builder.text_field(attribute_name, input_html_options.merge(value: object.value.join(',')))
        end
      
      end
      

      a coffeescpt sn-p:

      $('input.tag').tagsInput()
      

      对我的控制器进行了调整,遗憾的是必须稍微具体一点:

      @user = User.find(params[:id])
      attrs = params[:user]
      
      if @user.some_field.is_a? Array
        attrs[:some_field] = attrs[:some_field].split(',')
      end
      

      【讨论】:

        【解决方案6】:

        我有一个类似的问题,但想让用户输入一系列逗号分隔的元素作为数组的值。 我的迁移使用 rails 的新功能(或者是 postrges 的新功能?)将数组作为列类型

        add_column :articles, :links, :string, array: true, default: []
        

        然后表单可以接受这个输入

        <%= text_field_tag "article[links][]", @article.links %>
        

        这意味着控制器可以非常顺利地运行如下

        def create
          split_links
          Article.create(article_params)
        end
        
        private
        def split_links
          params[:article][:links] = params[:article][:links].first.split(",").map(&:strip)
        end
        
        
        params.require(:article).permit(links: [])
        

        现在用户可以输入任意数量的链接,并且表单在创建和更新时都能正常运行。而且我仍然可以使用强大的参数。

        【讨论】:

          【解决方案7】:

          对于那些使用简单表格的人,您可以考虑这个解决方案。基本上需要设置自己的输入并将其用作:array。然后您需要在控制器级别处理输入。

          #inside lib/utitilies
          class ArrayInput < SimpleForm::Inputs::Base
            def input
              @builder.text_field(attribute_name, input_html_options.merge!({value: object.premium_keyword.join(',')}))
            end
          end
          
          #inside view/_form
          
          ...
          = f.input :premium_keyword, as: :array, label: 'Premium Keyword (case insensitive, comma seperated)'
          
          #inside controller
          def update
            pkw = params[:restaurant][:premium_keyword]
            if pkw.present?
              pkw = pkw.split(", ")
              params[:restaurant][:premium_keyword] = pkw
            end
          
            if @restaurant.update_attributes(params[:restaurant])
              redirect_to admin_city_restaurants_path, flash: { success: "You have successfully edited a restaurant"}
            else
              render :edit
            end   
          end
          

          在您的情况下,只需将 :premium_keyword 更改为您的数组字段

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-07-02
            • 2015-10-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-01-30
            相关资源
            最近更新 更多