ruby-on-railsrubyform-for

trouble building a rails form to return paramaters in desired format


I'm trying to create a form where a user can add tickets to their accounts. The tickets are tiered (bronze, silver, gold) and I'm having a bit of trouble figuring out how to get the form to output the data in the format I want.

    <%= 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%>

this outputs the params Parameters: {"authenticity_token"=>"xxx", "ticket"=>{"tier"=>"5"}, "commit"=>"Get Tickets"}

whereas I want the parameters to return something along the lines of {"authenticity_token"=>"xxx", "ticket"=>{"tier"=>{'gold => 1, 'silver => 3, 'bronze' => 5 }, "commit"=>"Get Tickets"}

the Ticket model only contains the attributes user_id, raffle_id and tier.


Solution

  • EDIT

    I looked here: https://guides.rubyonrails.org/form_helpers.html#understanding-parameter-naming-conventions If you read that whole section you can see what I'm doing below. Here is a pure Rails solution that should work. I'll leave my HTML example for reference...

    <%= 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%>
    

    Since you didn't post your model code I'm not 100% sure this will work but let me know and we can tweak it as needed. This should give you the same result as my original answer below.

    original answer:

    You need to build the hash that you want returned using HTML format.

    <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]">
    

    This will return a hash in your params like:

    "ticket"=>{"tier"=>{"gold" => 1, "silver" => 3, "bronze" => 5 }
    

    You will need to make sure you whitelist this hash in your params with something like:

    params.require(:ticket).permit(:tier => [:gold, :sliver, :bronze])
    

    there is probably a way to make the standard form_for format spit out this HTML but I was unable to find it when working on similar code. If someone knows how to do that I'd be interested but it was easy just to build the HTML in my ERB file.