Rails与多态和抽象类的关联

时间:2019-06-12 18:20:10

标签: ruby-on-rails polymorphic-associations

这真的让我挠头。我正在处理与都从一个抽象类继承的多个类有关的多态关系。这工作得很好,但是当我尝试从多态关系访问关联的对象时遇到错误。这是我的实现:

class Foo < ApplicationRecord
  belongs_to :options, polymorphic: true
  accepts_nested_attributes_for :options

  def build_options(params)
    self.options = options_type.constantize.new(params)
  end
end

module Mod
  class Option < ApplicationRecord
    self.abstract_class = true
    has_one :foo, as: :options

    self.table_name_prefix
      'foo_'
    end
  end

  class Bar < Options
  end

  class Baz < Options
  end
end

到目前为止,它一直运行良好,但是当我尝试类似的操作时,我现在遇到了一个问题:

Bar.first.foo

我收到此错误:

ActiveRecord::AssociationNotFoundError (Association named 'foo' was not found on Foo::Bar; perhaps you misspelled it?)

让我感到奇怪的是,如果我打电话给Bar.first.methods,我会得到:foo作为选择。

您知道我需要做什么来解决此问题并仍然使用Options类继承吗?我知道我可以在子类上定义has_one,但是它适用于Options的所有子级,如果我可以将关联保留在那里,我想这么做。

编辑:剧情变厚了!在玩了一段时间之后,我现在意识到某些子类可以正常工作,但有些却没有。我也似乎找不到工作的类与没有工作的类之间的任何区别。

2 个答案:

答案 0 :(得分:1)

# /app/models/user.rb
class User < ActiveRecord::Base
  has_one :profile, as: :profileable, dependent: :destroy
end

# /app/models/business.rb
class Business < ActiveRecord::Base
  has_one :profile, as: :profileable, dependent: :destroy
end

# /app/models/profile.rb
class Profile < ActiveRecord::Base
  belongs_to :profileable, polymorphic: true
end

请参考上面的示例。

答案 1 :(得分:0)

您可能对拐点有疑问,belongs_to应该是单数而不是复数(option而不是options)。将has_one :foo, as: :options更改为as: :option相同。

table_name_prefix在这里不是必需的,在STI中,所有类都将共享同一张表。

此代码对我来说没有问题:

# app/models/foo.rb
class Foo < ApplicationRecord
  belongs_to :option, polymorphic: true
end

# app/models/mod/option.rb
module Mod
  class Option < ApplicationRecord
    self.abstract_class = true
    has_one :foo, as: :option

    self.table_name = "mod_options"
  end
end

# app/models/mod/baz.rb
module Mod
  class Baz < Option
  end
end

# app/models/bar.rb
module Mod
  class Bar < Option
  end
end