Не удалось сохранить новый связанный seo_setting в ассоциации has_one - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть 2 модели:

class Page < ApplicationRecord
  enum page_type: STATIC_PAGE_TYPES, _suffix: true
  has_one :seo_setting
  accepts_nested_attributes_for :seo_setting, update_only: true

  validates :title, :subtitle, length: { maximum: 50 }
  validates :page_type, uniqueness: true

  def to_param
    "#{id}-#{page_type}".parameterize
  end
end

и

class SeoSetting < ApplicationRecord
  mount_uploader :og_image, SeoSettingsOgImageUploader
  belongs_to :page

  validates :seo_title, :seo_description, :og_title, :og_description, :og_image, presence: true
end

Мои Page объекты создаются из файла seeds.rb, и когда я хочу их редактировать, яполучить ошибку: Failed to save the new associated seo_setting. В форме у меня есть это:

<div class="card-body">
      <%= form_for([:admin, @page]) do |f| %>
        <%= render 'shared/admin/error-messages', object: @page %>
        <div class="form-group">
          <%= f.label :title, t('admin.shared.title') %>
          <%= f.text_field :title, class: 'form-control' %>
        </div>
        <div class="form-group">
          <%= f.label :subtitle, t('admin.shared.subtitle') %>
          <%= f.text_field :subtitle, class: 'form-control' %>
        </div>
        <h3>SEO Settings</h3>
        <%= f.fields_for :seo_setting, f.object.seo_setting ||= f.object.build_seo_setting do |form| %>
          <div class="form-group">
            <%= form.label :seo_title, t('admin.shared.seo_title') %>
            <%= form.text_field :seo_title, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= form.label :seo_description, t('admin.shared.seo_description') %>
            <%= form.text_area :seo_description, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= form.label :og_title, t('admin.shared.og_title') %>
            <%= form.text_field :og_title, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= form.label :og_description, t('admin.shared.og_description') %>
            <%= form.text_area :og_description, class: 'form-control' %>
          </div>
          <div class="form-group">
            <%= form.label :og_image, t('admin.shared.og_image') %>
            <div class="row">
              <div class="col-lg-12">
                <%= image_tag(form.object.og_image.url, style: 'width: 100px') if form.object.og_image? %>
              </div>
            </div>
            <%= form.file_field :og_image %>
            <%= form.hidden_field :og_image_cache %>
          </div>
        <% end %>
        <div class="form-group">
          <%= f.submit t('admin.actions.submit'), class: 'btn btn-success' %>
          <%= link_to t('admin.actions.cancel'), admin_page_path(@page) , class: 'btn btn-default' %>
        </div>
      <% end %>
    </div>

Если я удаляю проверки из моей модели SeoSetting, все работает.Кажется, Rails не нравится эта часть: f.object.build_seo_setting, потому что она создает запись в моей базе данных.Любые идеи о том, как я могу решить эту проблему?Спасибо вперед.

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Просто нужно было изменить эту строку:

<%= f.fields_for :seo_setting, f.object.seo_setting ||= f.object.build_seo_setting do |form| %>

на эту:

<%= f.fields_for :seo_setting, @page.seo_setting.nil? ? @page.build_seo_setting : @page.seo_setting do |form| %>
0 голосов
/ 07 декабря 2018

Похоже, что проблема заключается здесь:

accepts_nested_attributes_for :seo_setting, update_only: true

в том, что вы разрешаете только обновление seo_setting при обновлении.

Затем, когда вы используете этот код:

f.object.seo_setting ||= f.object.build_seo_setting

Вы возвращаетесь к новому seo_setting, если связанный объект отсутствует.

Для этогоДля работы вам нужно либо удалить update_only: true, либо отобразить поля для ассоциации, если seo_setting уже существует.

...