【问题标题】:How to create a subset of nested attibutes with Ruby on Rails 5.2如何使用 Ruby on Rails 5.2 创建嵌套属性的子集
【发布时间】:2019-02-08 16:34:57
【问题描述】:

我的应用程序是一个以多种语言描述业务规则的知识库。名称和描述的翻译被设计为嵌套属性。它们不存在于主表中,仅存在于翻译表中:

  id            :integer          not null, primary key
  field_name    :string(30)       not null
  language      :string(2)        not null
  translation   :text
  created_at    :datetime         not null
  updated_at    :datetime         not null

业务规则可以有多种翻译,正如模型中声明的那样:

  has_many :name_translations, -> { where("field_name='name'") }, class_name: 'Translation'
  has_many :description_translations, -> { where("field_name='description'") }, class_name: 'Translation'

在创建时,我在业务规则控制器中初始化这些翻译:

  def new
    @business_rule = BusinessRule.new
    @business_rule.name_translations.build(language: user_language, field_name: 'name')
    @business_rule.name_translations.build(language: user_language, field_name: 'description')
  end

在 _form.html.rb 中,我只想显示当前用户语言的翻译。当然,在创建规则时,只有一种语言可用,但由于我使用相同的形式进行更新,我需要过滤嵌套翻译并仅保留当前用户的语言:

  <div class="row">
    <div class="col-md-1 text-right"> <%= t('Name')%>:
    </div>
    <%= f.fields_for :name_translations, @business_rule.name_translations.where('language=?', user_language) do |naming| %>
      <div class="col-md-8">
        <%= naming.text_field :translation, :class => "col-md-10" %>
      </div>
      <div class="col-md-1">
        <%= naming.hidden_field :field_name, :value => 'name' %>
      </div>
      <div class="col-md-1">
        <%= naming.hidden_field :language, :value => user_language %>
      </div>
    <% end %>
  </div>

这适用于编辑现有业务规则。但对于业务规则创建,嵌套字段不显示。

如果我删除了

@business_rule.name_translations.where('language=?', user_language)

表达式,显示输入字段。但这不符合编辑要求,因为所有翻译都会显示。

我怀疑这个表达式从数据库中查询嵌套属性,而不是控制器中的 new 方法初始化的那些。

有没有办法避免这种情况,或者过滤传递给 fields_for 方法的 :name_translations

感谢您的帮助!

【问题讨论】:

    标签: ruby-on-rails nested-forms


    【解决方案1】:

    如果我理解正确,您不需要为new 操作过滤 :name_translations。所以,在表单中你可以使用persisted?来检查记录是否存在:

    <%= f.fields_for :name_translations, @business_rule.name_translations.where('language=?', user_language) if @business_rule.persisted? do |naming| %>
    ...
    <% end %>
    

    多亏了这一点,您才能仅过滤现有记录的嵌套属性。

    【讨论】:

    • 我必须将条件括在括号中才能使其正常工作:(@business_rule.name_translations.where('language=?', user_language) if @business_rule.persisted?) 但这解决了问题。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-04
    • 2018-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多