Rails has_and_belongs_to_many只能单向运行

时间:2015-06-24 10:31:38

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord orm

我正在尝试在groups表和keywords表之间建立多对多的关系。

当我在我的控制器中时,我无法执行Keyword.groupsGroup.keywords,因为我得到了无方法错误。我检查了Group.methods,我只有这些相关的方法

  "before_add_for_groups_keywords",
  "before_add_for_groups_keywords?",
  "before_add_for_groups_keywords=",
  "after_add_for_groups_keywords",
  "after_add_for_groups_keywords?",
  "after_add_for_groups_keywords=",
  "before_remove_for_groups_keywords",
  "before_remove_for_groups_keywords?",
  "before_remove_for_groups_keywords=",
  "after_remove_for_groups_keywords",
  "after_remove_for_groups_keywords?",
  "after_remove_for_groups_keywords=",
  "before_add_for_keywords",
  "before_add_for_keywords?",
  "before_add_for_keywords=",
  "after_add_for_keywords",
  "after_add_for_keywords?",
  "after_add_for_keywords=",
  "before_remove_for_keywords",
  "before_remove_for_keywords?",
  "before_remove_for_keywords=",
  "after_remove_for_keywords",
  "after_remove_for_keywords?",
  "after_remove_for_keywords=",

Keyword.methods给我这些

的地方
  "before_add_for_keywords_groups",
  "before_add_for_keywords_groups?",
  "before_add_for_keywords_groups=",
  "after_add_for_keywords_groups",
  "after_add_for_keywords_groups?",
  "after_add_for_keywords_groups=",
  "before_remove_for_keywords_groups",
  "before_remove_for_keywords_groups?",
  "before_remove_for_keywords_groups=",
  "after_remove_for_keywords_groups",
  "after_remove_for_keywords_groups?",
  "after_remove_for_keywords_groups=",
  "before_add_for_groups",
  "before_add_for_groups?",
  "before_add_for_groups=",
  "after_add_for_groups",
  "after_add_for_groups?",
  "after_add_for_groups=",
  "before_remove_for_groups",
  "before_remove_for_groups?",
  "before_remove_for_groups=",
  "after_remove_for_groups",
  "after_remove_for_groups?",
  "after_remove_for_groups=",

我的模特

has_and_belongs_to_many :keywords

has_and_belongs_to_many :groups

我的数据库架构如下

  create_table "groups", force: :cascade do |t|
    t.integer  "member_id"
    t.string   "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false

  end

  add_index "groups", ["member_id"], name: "index_groups_on_member_id", using: :btree

  create_table "groups_keywords", id: false, force: :cascade do |t|
    t.integer "group_id"
    t.integer "keyword_id"
  end

  add_index "groups_keywords", ["group_id", "keyword_id"], name: "index_groups_keywords_on_group_id_and_keyword_id", unique: true, using: :btree

  create_table "keywords", force: :cascade do |t|
    t.string   "keyword"
    t.string   "keyword_hash"
    t.datetime "checked_at"
    t.datetime "created_at",              null: false
    t.datetime "updated_at",              null: false
  end

3 个答案:

答案 0 :(得分:2)

实例定义关联。

Keyword.groups确实不存在(作为类方法)。

然而,与Keyword#groups一样,Keyword.first.groups确实有效。原因是Keyword.first返回Keyword类的实例,Keyword类本身不是。

答案 1 :(得分:0)

当你执行Keyword.group(1)时,它并没有按照您的想法行事。它只找到所有关键字并将它们分组为1。

SELECT * "keywords".* FROM "keywords" GROUP BY 1

实际上,您实际上无法在类级别上调用这些方法,通过实例级别访问关联。正如你已定义它们has_and_belongs_to_many,你必须是复数关于它们,而不是单身。

keyword = Keyword.first
keyword.groups # Not 'group', and on instance level

答案 2 :(得分:0)

实现多对多关系的更好方法是使用has_many:通过习语:

class Keyword
  has_many :keyword_groups
  has_many :groups, :through => :keyword_groups

class Group
  has_many :keyword_groups
  has_many :keywords, :through => :keyword_groups

class KeywordGroup
  belongs_to :keyword
  belongs_to :group

如果您需要扩展连接模型,这将为您提供灵活性。