web-dev-qa-db-ja.com

Ruby on Rails:フォームで配列を送信する

配列である属性を持つモデルがあります。フォーム送信からその属性を設定する適切な方法は何ですか?

名前にカッコが含まれるフィールドを持つフォーム入力があると、入力からハッシュが作成されます。私はそれを受け取って、コントローラーでそれを踏んでアレイにマッサージする必要がありますか?

抽象度を低くする例:

class Article
  serialize :links, Array
end

リンク変数は、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" => "http://stackoverflow.com"

64
William Jones

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ヘルパーはnot自動的に配列トリックを行うように設定されているため、手動でname属性を作成する必要があることに注意してください。また、Railsヘルパーを使用する場合、チェックボックスには独自の問題があります。これは、チェックボックスヘルパーが未チェックのケースを処理するために追加の非表示フィールドを作成するためです。

88
Larry K
= simple_form_for @article do |f|
  = f.input_field :name, multiple: true
  = f.input_field :name, multiple: true
  = f.submit
51
stAndrei

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' } }
38
ecoologic

また、このような入力ヘルパーを渡すと、それぞれ独自の属性を持つコースの配列を取得できることもわかりました。

# 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    
8
Ana Franco

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

Coffeescrptスニペット:

$('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
7
Peter Ehrlich

シンプルなフォームを使用する場合は、このソリューションを検討できます。基本的に、独自の入力を設定し、それを: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を配列フィールドに変更してください

0
sovanlandy