ruby-on-rails - 为 STI 模型保存 STI 父类名称而不是 STI 子类名称具有许多直通、自相关和多态

标签 ruby-on-rails

伙计们,我们正在构建一种地址簿,我们有用户、联系人和一个名为 UserEntity 的父表。我们希望通过一个名为关系的表将它们以多对多关联的方式关联起来,这种关系必须在 UserEntity 表中的自相关中。

一位用户有很多联系人,一位联系人有很多用户。

稍后我们需要将新模型与用户相关联,因此关系模型必须是多态的。我们已经构建了这个:

class UserEntity < ActiveRecord::Base
  self.table_name = "users"
end

class User < UserEntity
  has_many :relationships, as: :relatable
  has_many :contacts, through: :relationships, source: :relatable, source_type "Contact"
end

class Contact < UserEntity
  has_many :relationships, as: :relatable
  has_many :users, through: :relationships, source: :relatable, source_type "User"
end

class Relationship < ActiveRecord::Base
  belongs_to :user
  belongs_to :relatable, polymorphic: true
end

但是当我们尝试保存关联时 user.contacts << contact relatable_type字段保存“UserEntity”值而不是“Contact”或“User”值。我们已经尝试过这样做,但没有任何有利的结果http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#label-Polymorphic+Associations

我们怎样才能做到 relatable_type value 保存模型名称(“Contact”||“User”)而不是 STI 父模型名称(“UserEntity”)?

最佳答案

这就是所谓的 STI base class ,Rails 将保存 Parent类,即使你调用了 subclass .我们有这方面的经验:

enter image description here

上面应该有NodeCompany ...

去年我花了一些时间研究这个;有一个gem调用 store_sti_base_class :

Notice that addressable_type column is Person even though the actual class is Vendor.

Normally, this isn't a problem, however it can have negative performance characteristic in certain circumstances. The most obvious one is that a join with persons or an extra query is required to find out the actual type of addressable.



绕过它 - 至少从 gem 的角度来看- 是扩展ActiveRecord这样它将保存模型的实际类,而不是其父类。

我拥有的唯一代码 - 已过时 - 如下:
#config/initializers/sti_base.rb
ActiveRecord::Base.store_base_sti_class = false

#lib/extensions/sti_base_class.rb
module Extensions
  module STIBaseClass #-> http://stackoverflow.com/questions/2328984/rails-extending-activerecordbase
    extend ActiveSupport::Concern

    included do
      class_attribute :store_base_sti_class
      self.store_base_sti_class = true
    end
  end

  # include the extension 
  ActiveRecord::Base.send(:include, STIBaseClass)

  ####

  module AddPolymorphic
    extend ActiveSupport::Concern

    included do #-> http://stackoverflow.com/questions/28214874/overriding-methods-in-an-activesupportconcern-module-which-are-defined-by-a-cl
      define_method :replace_keys do |record=nil|
        super(record)
        owner[reflection.foreign_type] = ActiveRecord::Base.store_base_sti_class ? record.class.base_class.name : record.class.name
        Rails.logger.info record.class.base_class.name
      end
    end
  end

  ActiveRecord::Associations::BelongsToPolymorphicAssociation.send(:include, AddPolymorphic)
end

由于我需要让这项工作正常进行,因此可能值得开玩笑。

关于ruby-on-rails - 为 STI 模型保存 STI 父类名称而不是 STI 子类名称具有许多直通、自相关和多态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35329578/

相关文章:

mysql - Rails 3 connection.execute IN语句参数数组语法

ruby-on-rails - Rails 中同一个类的多个关联的最佳实践?

ruby-on-rails - 将笔记本电脑上的本地 Rails 应用程序连接到 heroku 数据库

ruby-on-rails - 将文件夹添加到 Assets 管道路径?

javascript - 使用respond_to 做 |format| format.js 在模态中收藏照片后在模态中显示消息?

ruby-on-rails - 以表单形式构建嵌入的 mongoid 文档

mysql - 安装mysql2时出错

ruby-on-rails - 在 Rails 中查询 Postgres JSON 数组字段

ruby-on-rails - 退出 ActiveAdmin 后重定向

ruby-on-rails - Excon::Errors::Timeout:达到连接超时