如何创建多个自联接关系?

时间:2013-12-23 22:52:42

标签: ruby-on-rails activerecord

有很多关于如何使用Employee,Manager,Subordinate示例执行此操作的信息,但我在网上找不到任何其他内容。

我只是想创建一个模型架构,其中Word对象可以有许多反义词或许多同义词。这些反义词和同义词基本上都是单词对象。

我希望能够运行以下内容:

word = Word.create(name:'good')
antonym = Word.create(name:'bad')
word.antonyms << antonym
synonym = Word.create(name:'right')
word.synonyms << synonym

word.antonyms # This gives you a resultset of all of the antonyms related to that word.

我的模特:

# The following doesn't work right now
class Word < ActiveRecord::Base
  has_many :antonyms, :foreign_key => 'antonym_id', :class_name => 'Word'
  has_many :synonyms, :foreign_key => 'synonym_id', :class_name => 'Word'   
end

class Antonym < ActiveRecord::Base
  belongs_to :word, :foreign_key => "word_id", :class_name => "Word"
end

class Synonym < ActiveRecord::Base
  belongs_to :word, :foreign_key => "word_id", :class_name => "Word"
end

2 个答案:

答案 0 :(得分:0)

您不需要定义AntonymSynonym类。

通过在class_name定义中指定has_many选项,您暗示关系antonymssynonyms属于Word类型。

因此,请完全删除AntonymSynonym个类,并保留Word

# The following doesn't work right now
class Word < ActiveRecord::Base
  has_many :antonyms, :foreign_key => 'antonym_id', :class_name => 'Word'
  has_many :synonyms, :foreign_key => 'synonym_id', :class_name => 'Word'   
end

<强>更新

我认为关系可以是word has_many antonymsword has_many synonyms,而不是has_many...:through

class Word < ActiveRecord::Base
  has_many :antonyms
  has_many :synonyms
end

class Antonym < ActiveRecord::Base
  belongs_to :word
end

class Synonym < ActiveRecord::Base
  belongs_to :word
end

然后你的迁移(只是为了显示外键的位置):

class CreateWords < ActiveRecord::Migration
  def self.change
    create_table :words do |t| 
      ...
    end
  end
end

class CreateAntonyms < ActiveRecord::Migration
  def self.change
    create_table :antonyms do |t| 
      t.references :word
      ...
    end
  end
end

class CreateSynonyms < ActiveRecord::Migration
  def self.change
    create_table :synonyms do |t| 
      t.references :word
      ...
    end
  end
end

您可以想象这三个模型之间存在has_many...:through关系,即word has_many :synonyms through: :meanings和类似word has_many :antonyms through: :meanings。但是,联接表meanings对于每条记录都需要所有三个wordantonymsynonym,这可能并不总是令人满意,因为添加一个字不应该至少需要一个反义词和同义词。

答案 1 :(得分:0)

我认为您可以让Word模型保持原样,name列指定Word的类型。然后,在检索antonymsynonym时,您可以简单地将其范围化

scope :antonym, where(name: 'bad')
scope :synonym, where(name: 'right')

...

(当然你也可以这样说scope :type, ->(type) { where(name: type)} # Word.type('bad') will outputs all the antonyms...)