Параметры Rails возвращаются как ноль при обновлении хеш-атрибута модели - PullRequest
0 голосов
/ 06 февраля 2019

В моем приложении есть модель с именем Admin.

. У этого Admin может быть несколько электронных писем, и эти электронные письма хранятся в хеше с именем emails.Например,

{"sales"=>{"general"=>"sales@shop.com"},"support"=>{"general"=>"support@shop.com"}}

При создании формы для доступа к этим конкретным электронным письмам я могу отображать каждое отдельное электронное письмо во входных данных, но при попытке обновить модальное, ничего не меняется, так как мой admin_params[:emails] равен nil.

Ниже приведена моя форма в моем файле edit.html.erb:

<%= form_for @admin do |f| %>
    <dt class="col-sm-10">Admin Emails</dt>
    <%  @admin.emails.each do |type, subtype|%>
          <dt class="col-sm-10"> <%= f.label type %> </dt>
          <% if @admin.emails.include?(type) %>
            <% @admin.emails[type].each do |subtype_label, subtype_email| %>
              <%= f.fields :emails do |field| %>
                <dd class="col-sm-5"><%= field.label subtype_label %></dd>
                <dd class="col-sm-5"><%= field.text_field subtype_label, :value => subtype_email %></dd>
              <% end %>
            <% end %>
          <% end %>
    <% end %>

Вот метод set_admin, который вызывается перед любымдругой метод, кроме индекса:

def admin_params
  params.require(:admin).permit(:name, :emails)
end

Вот мой метод обновления:

def update
  binding.pry
  @admin.update(
    name: admin_params[:name],
    emails: admin_params[:emails]
  )

  redirect_to admin_path(@admin)
end

И, наконец, вот HTML-код, который обрабатывается при конкретном вводе:

<input value="emails" type="text" name="admin[emails][general]" id="admin_emails_general">

Любая подсказка, в чем моя проблема?Весь день царапал мне голову.

1 Ответ

0 голосов
/ 06 февраля 2019

Я бы посоветовал просто сделать это путём для простоты:

class Admin < ApplicationRecord
  has_many :emails, dependent: :destroy
  accepts_nested_attributes_for :emails, 
    reject_if: proc { |attributes| attributes['email'].blank? }
end

class Email < ApplicationRecord
  enum type: [:work, :home]
  belongs_to :admin
end

Это просто простая старая связь один-ко-многим и acceptpts_nested_attributes_for .

<%= form_for(@admin) do |f| %>
  <%= f.fields_for :emails do |ef| %>
     # ...
     <%= ef.select :type, Email.types.keys.map {|k| [k.humanize, k] } %>
     <%= ef.text_field :email %>
  <% end %>
  # ...
<% end %>

fields_for создает массив хэшей в параметрах, называя входные данные admin[emails_attributes][][email] и admin[emails_attributes][][type].

Ваше решение перезаписывает один и тот же параметр.Хотя вы можете обойти это, вручную установив атрибут имени, я бы посчитал, стоит ли оно усилий.

Чтобы внести в белый список вложенные параметры, вы передаете массив с ключами, которые хотите добавить в белый список:

def admin_params
  params.require(:admin).permit(:name, emails_attributes: [:type, :email])
end
...