【问题标题】:How to build a model form that has has_many relations on its own如何构建一个具有自身 has_many 关系的模型表单
【发布时间】:2016-03-14 10:44:37
【问题描述】:

我有一个 Phrasehas_many PhraseTranslation

app/models/phrase.rb

class Phrase < ActiveRecord::Base
  has_many :translatabilities
  has_many :translations, through: :translatabilities
  has_many :inverse_translatabilities, class_name: "Translatability", foreign_key: "translation_id"
  has_many :inverse_translations, through: :inverse_translatabilities, source: :phrase
  accepts_nested_attributes_for :translatabilities
end

app/models/phrases_controller.rb

class PhrasesController < ApplicationController
  def index
    @phrases = Phrase.all.page params[:page]
    @translations = @phrases.count.times.map do |i|
      translation = Phrase.new
      translation.translatabilities.build
      translation
    end
  end
end

我想为每个“短语”添加“可翻译性”表格。

app/views/phrases/index.html.erb

<table>
  <tbody>
  <% @phrases.each do |phrase| %>
      <tr>
        <td><%= phrase.text %></td>
      </tr>
      <tr>
        <td>
          <%= form_for @translations do |f| %>
              <%= f.text_field :text %>
              <%= f.submit 'translate' %>
              <%= f.fields_for :translatabilities do |t_form| %>
                  <%= t_form.hidden_field :id %>
              <% end %>
          <% end %>
        </td>
      </tr>
    <% end %>
  </tbody>
</table>

此代码存在无限循环错误。

undefined method `phrase_phrase_phrase_phrase_phrase_phrase_...

如何创建用于翻译原始短语的表单?

app/models/translatability.rb

class Translatability < ActiveRecord::Base
  belongs_to :phrase
  belongs_to :translation, :class_name => 'Phrase'
end

【问题讨论】:

  • 我知道性病。在这种情况下我应该使用 STI 吗?
  • 是的。因此,您可以同时拥有原始短语和翻译短语。这样一来,您就可以使用单个表继承来表达。
  • 不,短语实例也被视为其他短语的翻译,例如 Friend 同时是 User,但您不能使用 STI 创建 Friend 类。我是不是误会了?
  • 如果您想使用 STI 创建Friend,您只需从User 继承,如class Friend &lt; User; end。您可以对 TranslationPhrase 执行相同的操作

标签: ruby-on-rails has-many-through


【解决方案1】:

我认为您使用这种方法可能会使事情复杂化。如果我理解正确,您有可以翻译成多种语言的Phrases。在我看来,您真正想要的是一个 Phrase 模型,它定义了语言并具有允许其他翻译相关的参考。

Phrase 看起来像这样:

create_table :phrases do |t|
  t.text :body
  t.string :locale
  t.integer :translation_ref_id
end

Phrase 模型中,您可以定义translations 方法:

def translations
  self.class
    .where(translation_ref_id: translation_ref_id)
    .where.not(id: id)
end

在您的表单中,您将拥有多个 Phrases,而不是具有嵌套属性的单个 Phrase。在控制器中,您将为每个 Phrases 设置 translation_ref_id(您可以使用任何唯一标识符,递增整数 id 很好;您不需要单独的模型来跟踪 id)。

【讨论】:

  • 据我所知Phrase 模型是否有Translation 模型的参考ID,这意味着Translation has_many phrases,不是吗?
  • 我的回答是如何在不使用 STI 的情况下关联短语的示例。询问 Phrase 的翻译,返回其他 Phrase 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多