Ruby on Rails: przesyłanie tablicy w formie
Mam model, który ma atrybut, który jest tablicą. Jaki jest właściwy sposób na wypełnienie tego atrybutu z formularza?
Wiem, że wprowadzenie formularza z polem, którego nazwa zawiera nawiasy, tworzy hash z wejścia. Czy powinienem to wziąć i przechodzić przez kontroler, żeby wmasować go w tablicę?
Przykład, aby uczynić go mniej abstrakcyjnym:
class Article
serialize :links, Array
end
Zmienna links ma postać tablicy adresów URL, czyli [["http://www.google.com"], ["http://stackoverflow.com"]]
Kiedy używam czegoś podobnego do poniższego w moim formularzu, tworzy to hash:
<%= hidden_field_tag "article[links][#{url}]", :track, :value => nil %>
Wynikowy hash wygląda tak:
"links" => {"http://www.google.com" => "", "http://stackoverflow.com" => ""}
Jeśli nie podam adresu url w nazwie linku, dodatkowe wartości będą się wzajemnie blokować:
<%= hidden_field_tag "article[links]", :track, :value => url %>
Wynik wygląda następująco: "links" => "http://stackoverflow.com"
6 answers
Jeśli twój formularz html zawiera pola wejściowe z pustymi nawiasami kwadratowymi, to zostaną one zamienione w tablicę wewnątrz params w kontrolerze.
# 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
Dodany:
Zauważ, że helpery rails są, a nie ustawione, aby wykonać sztuczkę z tablicami automatycznie-magicznie. Być może będziesz musiał ręcznie utworzyć atrybuty name. Ponadto, pola wyboru mają swoje własne problemy, jeśli używasz helperów rails, ponieważ helpery te tworzą dodatkowe ukryte pola do obsługi niezaznaczonej sprawy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-22 03:28:51
= simple_form_for @article do |f|
= f.input_field :name, multiple: true
= f.input_field :name, multiple: true
= f.submit
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-30 22:11:30
TL; DR wersja HTML []
konwencja:
Tablica:
<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">
Params otrzymane:
{ course: { track_codes: ['a', 'b', 'c'] } }
Hash
<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">
Params otrzymane:
{ course: { track_codes: { x: 'a', y: 'b', z: 'c' } }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-27 00:41:16
Dowiedziałem się również, że jeśli przekażesz swój helper wejściowy w ten sposób, otrzymasz tablicę kursów, każdy z własnymi atrybutami.
# 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-26 21:35:18
Właśnie skonfigurowałem rozwiązanie używając jquery taginput:
Http://xoxco.com/projects/code/tagsinput/
Napisałem niestandardowe rozszerzenie 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
Fragment coffeescrpt:
$('input.tag').tagsInput()
I poprawkę do mojego kontrolera, która niestety musi być nieco specyficzna:
@user = User.find(params[:id])
attrs = params[:user]
if @user.some_field.is_a? Array
attrs[:some_field] = attrs[:some_field].split(',')
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-07 22:49:08
Dla tych, którzy używają prostej formy, można rozważyć To rozwiązanie. Zasadniczo trzeba skonfigurować własne wejście i użyć go jako: array. Następnie musisz obsługiwać dane wejściowe na poziomie kontrolera.
#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
W Twoim przypadku wystarczy zmienić: premium_keyword na pole tablicy
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-05 04:12:43