我正在尝试在 Rails 中构建一个简单的同义词库应用程序,其中单词表中的单词将通过同义词对的连接表与表中的其他单词具有多重、自连接关系。
我的 SynonymPair 类构建如下:
class SynonymPair < ActiveRecord::Base
belongs_to :word1, class_name: :Word
belongs_to :word2, class_name: :Word
end
这个词库程序的一个关键方面是,一个词是在 word1 还是 word2 列中都无关紧要。word1 是 word2 的同义词,反之亦然。
为了让我的 Words 类返回给定单词的 SynonymPairs 和 Synonyms,我编写了一个 SQL 查询:
class Word < ActiveRecord::Base
def synonym_pairs
#joins :synonym_pairs and :words where either word1_id OR word2_id matches word.id.
sql = <<-SQL
SELECT synonym_pairs.id, synonym_pairs.word1_id, synonym_pairs.word2_id, words.word FROM synonym_pairs
JOIN words ON synonym_pairs.word1_id = words.id WHERE words.word = ?
UNION SELECT synonym_pairs.id, synonym_pairs.word1_id, synonym_pairs.word2_id, words.word FROM synonym_pairs
JOIN words ON synonym_pairs.word2_id = words.id WHERE words.word = ?
SQL
#returns synonym_pair objects from the result of sql query
DB[:conn].execute(sql,self.word,self.word).map do |element|
SynonymPair.find(element[0])
end
end
def synonyms
self.synonym_pairs.map do |element|
if element.word1 == self
element.word2
else
element.word1
end
end
end
end
此代码按预期工作。但是,它没有利用 ActiveRecord 中的关联模型。所以,我想知道是否可以在 Words 类中编写一个 has_many :synonyms_pairs/has_many :synonyms through: :synonym-pairs 自定义关系查询,而不是像我上面那样写出整个 SQL 查询。换句话说,我很好奇是否可以将我的 SQL 查询转换为 Rails 自定义关系查询。
注意,我尝试了以下自定义关系查询:
class Word < ActiveRecord::Base
has_many :synonym_pairs, ->(word) { where("word1_id = ? OR word2_id = ?", word.id, word.id) }
has_many :synonyms, through: :synonym_pairs
end
但是,在传递了一些 Word/SynonymPair 种子后,当我尝试调用 word#synonym_pairs 时,它返回了一个“ActiveRecord:Associations:CollectionProxy”,当我调用 word#synonyms 时出现以下错误:
[17] pry(main)> w2 = Word.create(word: "w2")
=> #<Word:0x00007ffd522190b0 id: 7, word: "w2">
[18] pry(main)> sp1 = SynonymPair.create(word1:w1, word2:w2)
=> #<SynonymPair:0x00007ffd4fea2230 id: 6, word1_id: 6, word2_id: 7>
[19] pry(main)> w1.synonym_pairs
=> #<SynonymPair::ActiveRecord_Associations_CollectionProxy:0x3ffea7f783e4>
[20] pry(main)> w1.synonyms
ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) "synonym" or :synonyms in model SynonymPair. Try 'has_many :synonyms, :through => :synonym_pairs, :source => <name>'. Is it one of word1 or word2?
获取自定义关系查询或任何类型的自联接模型在这里工作的任何其他想法?