尝试通过我正在使用的关联来学习如何正确导航has_many并且我正在碰壁砖。我在这里抽象了这些类,以便它们更易于联系。
一本书有很多字。 一个角色有很多书。 与典型的hmt关联不同的是,当一个角色与一本书相关联时,它会被添加为“好人”或“坏人”,例如:
book.bad_guys << character
我能够为book.good_guys提取结果就好了。什么让我成为一个循环是每当我想走另一条路,拿一个角色并找出他与之相关的书时,它会返回一个Book :: ActiveRecord_Associations_CollectionProxy而不是一个实际的结果列表。
如果我做了character.books.first这就是输出(请注意它是如何尝试查找“good_guy”属性而不是从作为连接表一部分的书和字符列中删除的)
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'
我怀疑我需要确定角色模型如何通过直通表进行搜索,最终搜索到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
答案 0 :(得分:2)
你的第一个问题是:
class BookCharacter < ApplicationRecord
belongs_to :character
belongs_to :book, :foreign_key => :bad_guy
belongs_to :book, :foreign_key => :good_guy
这里有两个问题。首先,您不能双重声明belongs_to :book
。其次,当您说:foreign_key => :good_guy
时,rails希望BookCharacter
将有一个名为good_guy
的字段。它没有。这就是你得到的原因:
no such column: book_characters.good_guy
所以,你需要更像的东西:
class BookCharacter < ApplicationRecord
belongs_to :character
belongs_to :book
然后,我相信你的范围看起来像:
class Character < ApplicationRecord
has_many :book_characters
has_many :books, -> { Book.where(book_characters: book_characters) }
我并非100%确定book_characters: book_characters
位将按宣传的方式运行。所以,你可以尝试类似的东西:
class Character < ApplicationRecord
has_many :book_characters
has_many :books, -> { Book.where(id: book_characters.pluck(:book_id)) }
说了这么多,我怀疑这个:
book.bad_guys << character
正在做你认为的事情。因为,你似乎没有在任何地方坚持'good_guy'或'bad_guy'的概念。所以,你可能并没有真正记录谁是好人,谁不是谁。
最后,我注意到你正在使用SQLite。我不知道你最终会在哪里部署你的应用程序。但是,你可能想要通过考虑。例如,Heroku不使用SQLite并在Heroku上部署,您需要转换为postgresql。面条的东西。