Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails/ActiveRecord:在一侧是多态的情况下,建立多对多关联的正确方法是什么?_Ruby On Rails_Activerecord - Fatal编程技术网

Ruby on rails Rails/ActiveRecord:在一侧是多态的情况下,建立多对多关联的正确方法是什么?

Ruby on rails Rails/ActiveRecord:在一侧是多态的情况下,建立多对多关联的正确方法是什么?,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,我有徽章,评论和项目。评论和项目可以有很多徽章。徽章可以有许多评论和项目 徽章通过名为reactions的联接表指向注释和项目 # reaction.rb class Reaction < ApplicationRecord belongs_to :badge belongs_to :reaction_target, polymorphic: true end # badge.rb class Badge < ApplicationRecord has_many :re

我有
徽章
评论
项目
。评论和项目可以有很多徽章。徽章可以有许多评论和项目

徽章通过名为reactions的联接表指向注释和项目

# reaction.rb
class Reaction < ApplicationRecord
  belongs_to :badge
  belongs_to :reaction_target, polymorphic: true
end

# badge.rb
class Badge < ApplicationRecord
  has_many :reactions
  has_many :reaction_targets, through: :reactions
end

# comment.rb
class Comment < ApplicationRecord
  has_many :reactions, as: :reaction_target
  has_many :badges, through: :reactions
end

# project.rb
class Project < ApplicationRecord
  has_many :reactions, as: :reaction_target
  has_many :badges, through: :reactions
end
我正在努力处理这件事。我错过了什么?我哪里出错了?是什么阻止我从徽章方面确定反应目标?

TL;博士: app/models/badge.rb

class Badge < ApplicationRecord
  has_many :reactions
  
  has_many :reaction_target_comments, through: :reactions, source: :reaction_target, source_type: 'Comment'
  has_many :reaction_target_projects, through: :reactions, source: :reaction_target, source_type: 'Project '
  # ... etc
end
^上面的代码看起来很直观,对吗。。。因为它应该返回一个不同类型记录的数组,这很有意义,因为它是一个多态关系,对吗?是的,这是完全正确的,但在应该生成什么样的SQL字符串方面会出现问题。请参见下面的SQL等效示例:

puts badge.reaction_targets
# =>  SELECT "WHAT_TABLE_1".* FROM "WHAT_TABLE_1" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_2".* FROM "WHAT_TABLE_2" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_3".* FROM "WHAT_TABLE_3" INNER JOIN reactions ...
#     ... etc
^…因为预期
reaction\u目标
会有不同的模型实例,那么想象一下,要获取所有记录,需要执行上面的SQL吗?虽然,我认为可以获得所有这些,但它可能不是一个直接的SQL语句,而是一些应用程序端Ruby代码逻辑的组合。而且,返回类型不应该是
ActiveRecord::Associations::CollectionProxy
,而可能是一种新类型的对象,专门用于满足这种
多态关系。我的意思是想象一下,如果你做了如下的事情,否则:

badge.reaction_targets.where(is_enabled: true, first_name: 'Hello')
# or even more complex:
badge.reaction_targets.joins(:users).where(users: { email: 'email@example.com' }).
^。。。我认为对于多态联接,上面没有直接的SQL语句,因此这可能就是为什么需要为不同的“模型”添加
source
source\u type
,就像我上面的回答一样

可能的解决办法 如果返回
数组
对象而不是正常的
ActiveRecord::Associations::CollectionProxy
对象,则可以执行以下操作。(尽管您仍然必须指定每个多态
都有许多关系,将来可能还会添加更多。)

class-Badge
用法示例:
badge=badge.find(1)
放置badge.reaction\u目标
# =>[,
#    ,
#    ,
#    ,
#    ...]
TL;博士: app/models/badge.rb

class Badge < ApplicationRecord
  has_many :reactions
  
  has_many :reaction_target_comments, through: :reactions, source: :reaction_target, source_type: 'Comment'
  has_many :reaction_target_projects, through: :reactions, source: :reaction_target, source_type: 'Project '
  # ... etc
end
^上面的代码看起来很直观,对吗。。。因为它应该返回一个不同类型记录的数组,这很有意义,因为它是一个多态关系,对吗?是的,这是完全正确的,但在应该生成什么样的SQL字符串方面会出现问题。请参见下面的SQL等效示例:

puts badge.reaction_targets
# =>  SELECT "WHAT_TABLE_1".* FROM "WHAT_TABLE_1" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_2".* FROM "WHAT_TABLE_2" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_3".* FROM "WHAT_TABLE_3" INNER JOIN reactions ...
#     ... etc
^…因为预期
reaction\u目标
会有不同的模型实例,那么想象一下,要获取所有记录,需要执行上面的SQL吗?虽然,我认为可以获得所有这些,但它可能不是一个直接的SQL语句,而是一些应用程序端Ruby代码逻辑的组合。而且,返回类型不应该是
ActiveRecord::Associations::CollectionProxy
,而可能是一种新类型的对象,专门用于满足这种
多态关系。我的意思是想象一下,如果你做了如下的事情,否则:

badge.reaction_targets.where(is_enabled: true, first_name: 'Hello')
# or even more complex:
badge.reaction_targets.joins(:users).where(users: { email: 'email@example.com' }).
^。。。我认为对于多态联接,上面没有直接的SQL语句,因此这可能就是为什么需要为不同的“模型”添加
source
source\u type
,就像我上面的回答一样

可能的解决办法 如果返回
数组
对象而不是正常的
ActiveRecord::Associations::CollectionProxy
对象,则可以执行以下操作。(尽管您仍然必须指定每个多态
都有许多关系,将来可能还会添加更多。)

class-Badge
用法示例:
badge=badge.find(1)
放置badge.reaction\u目标
# =>[,
#    ,
#    ,
#    ,
#    ...]
badge = Badge.find(1)
puts badge.reaction_targets.to_a
# => [<Comment id: 1>,
#     <Project id: 45>,
#     <SomeModel id: 99>,
#     <COmment id: 3>,
#     ...]
puts badge.reaction_targets
# =>  SELECT "WHAT_TABLE_1".* FROM "WHAT_TABLE_1" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_2".* FROM "WHAT_TABLE_2" INNER JOIN reactions ...
#     SELECT "WHAT_TABLE_3".* FROM "WHAT_TABLE_3" INNER JOIN reactions ...
#     ... etc
badge.reaction_targets.where(is_enabled: true, first_name: 'Hello')
# or even more complex:
badge.reaction_targets.joins(:users).where(users: { email: 'email@example.com' }).
class Badge < ApplicationRecord
  has_many :reactions

  has_many :reaction_target_comments, through: :reactions, source: :reaction_target, source_type: 'Comment'
  has_many :reaction_target_projects, through: :reactions, source: :reaction_target, source_type: 'Project'

  def reaction_targets
    reaction_target_comments.to_a + reaction_target_projects.to_a
  end
end
badge = Badge.find(1)
puts badge.reaction_targets
# =>[<Comment id: 1>,
#    <Comment id: 45>,
#    <Project id: 99>,
#    <Project id: 3>,
#    ...]