#ruby-on-rails #ruby #form-for
#ruby-on-rails #ruby #форма-для
Вопрос:
Я пытаюсь создать форму, в которой пользователь может добавлять заявки в свои учетные записи. Билеты многоуровневые (бронзовые, серебряные, золотые), и у меня возникли небольшие проблемы с выяснением, как заставить форму выводить данные в нужном мне формате.
<%= form_for(@ticket) do |f|%>
<%=f.label :tier_gold, "Gold" %>: <br>
<%=f.number_field :tier%><br>
<%=f.label :tier_silver, "Silver" %>:<br>
<%=f.number_field :tier%><br>
<%=f.label :tier_bronze, "Bronze" %>:<br>
<%=f.number_field :tier%> <br><br>
<%= f.submit "Get Tickets" %>
<%end%>
это выводит параметры Parameters: {"authenticity_token"=>"xxx", "ticket"=>{"tier"=>"5"}, "commit"=>"Get Tickets"}
в то время как я хочу, чтобы параметры возвращали что-то вроде {"authenticity_token"=>"xxx", "ticket"=>{"tier"=>{'gold => 1, 'silver => 3, 'bronze' => 5 }, "commit"=>"Get Tickets"}
модель билета содержит только атрибуты user_id, raffle_id и tier.
Комментарии:
1. Пожалуйста, отправьте код модели и контроллера для @ticket. Вы пытаетесь получить хэш хэшей в качестве возвращаемого значения. Вам нужно будет сгенерировать HTML по строкам
<input name="ticket[tier][gold]" value="1"> ... <input name="ticket[tier][silver]" value="3">
вашего кода формы, это будет немного сложнее, чем то, что у вас есть.
Ответ №1:
Редактировать
Я посмотрел здесь: https://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions Если вы прочтете весь этот раздел, то сможете увидеть, что я делаю ниже. Вот чистое решение Rails, которое должно работать. Я оставлю свой пример HTML для справки…
<%= form_for(@ticket) do |f|%>
<%= fields_for(:tier) do |fl|%>
<%=fl.label :gold, "Gold" %>:
<br>
<%=fl.number_field :gold %>
<br>
<%=fl.label :silver, "Silver" %>:
<br>
<%=fl.number_field :silver %>
<br>
<%=fl.label :bronze, "Bronze" %>:
<br>
<%=fl.number_field :bronze %>
<br>
<%end%>
<%end%>
Поскольку вы не опубликовали свой код модели, я не уверен на 100%, что это сработает, но дайте мне знать, и мы сможем настроить его по мере необходимости. Это должно дать вам тот же результат, что и мой первоначальный ответ ниже.
оригинальный ответ:
Вам нужно создать хэш, который вы хотите вернуть, используя формат HTML.
<label for="tier_gold"> Gold: </label><br>
<input type="number_field" name="ticket[tier][gold]">
<br>
<label for="tier_gold"> Silver: </label><br>
<input type="number_field" name="ticket[tier][silver]">
<br>
<label for="tier_gold"> Bronze: </label><br>
<input type="number_field" name="ticket[tier][bronze]">
Это вернет хэш в ваших параметрах, например:
"ticket"=>{"tier"=>{"gold" => 1, "silver" => 3, "bronze" => 5 }
Вам нужно будет убедиться, что вы внесли этот хэш в белый список в своих параметрах с помощью чего-то вроде:
params.require(:ticket).permit(:tier => [:gold, :sliver, :bronze])
вероятно, есть способ заставить стандартный form_for
формат выдать этот HTML, но я не смог найти его при работе над аналогичным кодом. Если кто-то знает, как это сделать, мне было бы интересно, но было легко просто создать HTML в моем ERB-файле.
Комментарии:
1. огромное спасибо! я добавил attr_accessors в свою модель tickets (:bronze, :silver, :gold), и она начала работать, но ваше решение — это очень простой способ справиться с этим.
2. Если у вас был метод, который возвращал различные уровни, скажем
ticket.levels
, который возвращал массив уровней, т. Е.[:bronze, :silver, :gold]
Вы могли бы еще больше сжать его с помощью цикла, в котором была только одна запись, которая создавала бы каждый из элементов формы в цикле. Если у вас будут только эти три, я бы не стал беспокоиться. Но если вы предвидели список, который может расшириться, вы могли бы использовать эту идею, а затем в любое время, когда вы добавляете в массив, возвращаемыйticket.levels
методом, он автоматически генерирует необходимые поля формы.
Ответ №2:
Вы можете попробовать, как показано ниже, чтобы получить желаемый формат для параметров —
<%= form_for(@ticket) do |f| %>
<%=f.label :tier_gold, "Gold" %>: <br>
<%=f.number_field :gold%><br>
<%=f.label :tier_silver, "Silver" %>:<br>
<%=f.number_field :silver %><br>
<%=f.label :tier_bronze, "Bronze" %>:<br>
<%=f.number_field :bronze %> <br><br>
<%= f.submit "Get Tickets" %>
<% end %>
и добавьте приведенный ниже код в свою модель билета
attr_accessor :gold, :silver, :bronze
Комментарии:
1. ‘неопределенный метод `gold’ для #<Ticket:0x00007f2760367188>’ единственными атрибутами для класса ticket являются user_id, raffle_id и tier
2. Я думаю, что тогда, добавив attr_accessor, Ticket также сможет получить доступ к gold, silver и bronze.
attr_accessor :gold, :silver, :bronze