проблема с созданием формы rails для возврата параметров в желаемом формате

#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