【发布时间】:2017-07-27 21:23:55
【问题描述】:
试图学习如何通过我正在使用的关联正确导航 has_many,但我遇到了困难。我已经抽象了这里的类,以便它们更容易关联。
一本书有很多人物。 一个角色有很多书。 它与典型的 hmt 关联的不同之处在于,当一个角色与一本书关联时,它要么被添加为“好人”,要么被添加为“坏人”,例如:
book.bad_guys << character
我能够为 book.good_guys 提取结果就好了。让我陷入循环的是,每当我想反其道而行之,获取一个角色并找出他与哪些书相关联时,它会返回 Book::ActiveRecord_Associations_CollectionProxy 而不是实际的结果列表。
如果我执行 character.books.first 这就是输出(注意它是如何尝试查找“good_guy”属性而不是离开作为连接表一部分的 book 和 character 列)
Document Load (1.1ms) SELECT "books".* FROM "books" INNER JOIN "book_characters" ON "books"."id" = "book_characters"."good_guy" WHERE "book_characters"."character_id" = ? ORDER BY "books"."id" ASC LIMIT ? [["character_id", 1], ["LIMIT", 1]]
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: book_characters.good_guy: SELECT "books".* FROM "books" INNER JOIN "book_characters" ON "books"."id" = "book_characters"."good_guy" WHERE "book_characters"."character_id" = ? ORDER BY "books"."id" ASC LIMIT ?
from /home/linux/.rvm/gems/ruby-2.3.1/gems/sqlite3-1.3.11/lib/sqlite3/database.rb:91:in `initialize'
我怀疑我需要确定 Character 模型如何执行它的搜索范围,即搜索 through 表并最终搜索到 Book 表,但我没有取得任何成功。
是否可以在字符模型上添加一个范围来修改它如何搜索直通表?或者我还需要做些什么来查找相关记录?提前感谢您提供的任何帮助!
class Character < ApplicationRecord
has_many :book_characters
has_many :books, -> { where(book_characters: ("character = :character.id")) }, :through => :book_characters # I don't think my wording is correct here
class Book < ApplicationRecord
has_many :book_characters
has_many :good_guys, through: :book_characters, :source => "character"
has_many :bad_guys, through: :book_characters, :source => "character"
class BookCharacter < ApplicationRecord
belongs_to :character
belongs_to :book, :foreign_key => :bad_guy
belongs_to :book, :foreign_key => :good_guy
这里是 BookCharacters 的迁移...
class CreateBookCharacters < ActiveRecord::Migration[5.0]
def change
create_table :book_characters do |t|,
t.references :book, foreign_key: true
t.references :entity
【问题讨论】:
-
澄清一下,您希望能够进行类似
character.books的查询并让它返回显示该角色所在的所有书籍的关系? -
@quicklikearabbit:是的,这就是我所追求的
标签: ruby-on-rails activerecord associations