2017-07-27 42 views
1

試圖學習如何通過我正在使用的關聯正確導航has_many,並且我擊中了一堵磚牆。我已經在這裏抽象了這些類,以使它們更容易關聯。如何通過使用自定義鍵名稱的關聯來確定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'  

我懷疑我需要確定角色模型如何通過直通表進行搜索並最終到達書籍表,但我沒有取得任何成功。

是否可以在角色模型上添加一個作用域以修改它在通過表中的搜索方式?還是有什麼我需要做的,以找到相關的記錄?預先感謝您提供的任何幫助!

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 
+1

只是爲了澄清一下,你希望能夠做一個像'character.books'這樣的查詢,並讓它返回一個顯示所有字符所在書籍的關係? – quicklikerabbit

+0

@quicklikearabbit:是的,那就是我之後 – Spectator6

回答

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時,ra​​ils期望BookCharacter將會有一個名爲good_guy的字段。它沒有。這就是爲什麼你會得到:

no such column: book_characters.good_guy 

所以,你需要更多的東西一樣:

class BookCharacter < ApplicationRecord 
    belongs_to :character 
    belongs_to :book 

然後,我相信你的示波器可以看起來像:

我不是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。麪條上的東西。

+0

有趣......感謝您的詳細回覆,很多咀嚼!因此,如果我正確地閱讀了你的內容,如果我想要從bad_guys中分離出good_buys,那麼將它們作爲介入模型添加會更有意義?或者也許使用某種多態關聯?最終的目標是能夠採取一本書的善意和壞話,並在它們之間創造一個相遇,但是這次相遇會被這本書「擁有」,所以這就是促成這個分離的原因......(真正的目標是代表各方之間的合法交易) – Spectator6

+1

有多種方式可以做你以後的事情。我不希望你需要任何新的模型 - 你可以跟蹤'BookCharacter'上的好/壞人。但是,你需要一個新的領域。而且,你需要改變你爲書中添加角色的方式(再次,多種方式)。給它一個去,讓我們知道如果你有具體問題。 – jvillian

+0

>「如果您有特定問題,請告訴我們並告訴我們。」謝謝你的幫助jvillian,會做! :豎起大拇指: – Spectator6

相關問題