Rails / ActiveRecord:我可以与具有不同ID类型的表建立多态关系吗?

时间:2019-02-21 19:08:43

标签: ruby-on-rails activerecord

建立多对多态关联是真正的绕线者。我已经在这个上度过了一个下午,而我的精力已经耗尽。

我有两个模型,<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> Input 1 <input type="hidden" value="1" class="testfieldvalue"> <div class="testfieldshow" name="testfieldshow" style="display: none"> <label class="Field_1_label" style="display: none">Field 1</label> <input type="text" class="Field_1" name ="Field_1" style="display: none"> <label class="Field_2_label" style="display: none">Field 2</label> <input type="text" class="Field_2" name ="Field_2" style="display: none"> </div> <br> Input 2 <input type="hidden" value="2" class="testfieldvalue"> <div class="testfieldshow" name="testfieldshow" style="display: none"> <label class="Field_1_label" style="display: none">Field 1</label> <input type="text" class="Field_1" name ="Field_1" style="display: none"> <label class="Field_2_label" style="display: none">Field 2</label> <input type="text" class="Field_2" name ="Field_2" style="display: none"> </div>Comment。我有第三个模型Project。用户可以通过添加徽章来对评论或项目做出反应。评论和项目将为Badge

我想我了解如何进行多对多态部分。问题是reaction_targetsComment具有不同的ID类型。 ProjectComment索引,而bigint使用Project

我的联接表称为uuidreactions通过它指向Badge

reaction_targets

联接表中的每一行都指向一个徽章和一个目标。

    class Badge < ApplicationRecord
      has_many :reactions
      has_many :reaction_targets, through: :reactions
    end

我已经确定与 class CreateReactions < ActiveRecord::Migration[5.2] def change create_table :reactions do |t| t.references :reaction_target, polymorphic: true t.references :badge end end end 的关联是多态的。

reaction_target

我将 class Reaction < ApplicationRecord belongs_to :badge belongs_to :reaction_target, polymorphic: true end 指向联接表。

Comment

一切正常:

    class Comment < ApplicationRecord
      has_many :reactions, as: :reaction_target
      has_many :badges, through: :reactions
    end

但是在 > b = Badge.first_or_create(name: 'badge') > c = Comment.create > c.badges #=> [] > c.badges << b #=> (0.2ms) SAVEPOINT active_record_1... 方面却有所不同。

我以相同的方式建立关联:

Project

但是效果不一样。

    class Project < ApplicationRecord
      has_many :reactions
      has_many :badges, through: :reactions
    end

我首先看到的是 > b = Badge.first_or_create(name: 'badge') > p = Project.create > p.badges #=> #<Badge::ActiveRecord_Associations_CollectionProxy:0x3fdc34cde54c> 返回的对象不是空数组。

当我尝试将徽章添加到收藏夹时,出现错误:

#badges

我在 (1.5ms) SAVEPOINT active_record_1 ActiveRecord::StatementInvalid: PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block : SAVEPOINT active_record_1 from /Users/123/.rvm/gems/ruby-2.6.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:75:in `async_exec' Caused by PG::InFailedSqlTransaction: ERROR: current transaction is aborted, commands ignored until end of transaction block from /Users/123/.rvm/gems/ruby-2.6.0/gems/activerecord-5.2.2/lib/active_record/connection_adapters/postgresql/database_statements.rb:75:in `async_exec' 中看到,schema.rb应该是reaction_target_id

bigint

我认为上面的错误是由于这个原因。是否可以与具有不同索引类型的表建立多态关系?如果是这样,我需要怎么做才能向项目添加徽章?如果没有,是否有解决方法?

1 个答案:

答案 0 :(得分:1)

您在Project中的as: :reaction_target关联中缺少has_many :reactions

class Project < ApplicationRecord
  has_many :reactions, as: :reaction_target
  has_many :badges, through: :reactions
end

这就是指定您声明为reaction_target的多态关联的原因。