无法在 has_one 关联上保存新的关联 seo_setting
Failed to save the new associated seo_setting on has_one association
我有 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
,因为它在我的数据库中创建了一条记录。关于如何解决此问题的任何想法?先谢谢了。
看起来问题出在这里:
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
已经存在,则只呈现关联字段。
只需更改这一行:
<%= 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| %>
OP 接受的答案,fields_for 行内的条件,也适用于多态关联和嵌套形式 (fields_for)。感谢亚历克斯
我有 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
,因为它在我的数据库中创建了一条记录。关于如何解决此问题的任何想法?先谢谢了。
看起来问题出在这里:
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
已经存在,则只呈现关联字段。
只需更改这一行:
<%= 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| %>
OP 接受的答案,fields_for 行内的条件,也适用于多态关联和嵌套形式 (fields_for)。感谢亚历克斯