質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.37%

rails5のmodel内のアソシエーションのforeign_keyの書き方

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 809

score 13

versionなど

  • ruby 2.6.4
  • rails 5.2.3
  • sqlite3 3.29.0

やりたいこと

お金の受け渡し記録のようなものを作りたい。  
Membersテーブルにidとユーザ名。  
MoneyRecordsテーブルにidと差出人、受取人、金額が記録されている。  
参考にしたのは以下の記事:
[Rails] 同じmodelを参照する外部キーを一つのmodelでもつ方法

スキーマ

# 一部抜粋
  create_table 'members', force: :cascade do |t|
    t.string 'member_name'
    t.string 'email'
    t.string 'password_digest'
    t.string 'remember_token'
    t.datetime 'created_at', null: false
    t.datetime 'updated_at', null: false
  end

  create_table 'money_records', force: :cascade do |t|
    t.float 'price'
    t.integer 'receiver_id'
    t.integer 'sender_id'
    t.datetime 'created_at', null: false
    t.datetime 'updated_at', null: false
    t.index ['receiver_id'], name: 'index_money_records_on_receiver_id'
    t.index ['sender_id'], name: 'index_money_records_on_sender_id'
  end

モデル

class MoneyRecord < ApplicationRecord
  belongs_to :receiver , class_name: 'Member', foreign_key: 'receiver_id'
  belongs_to :sender   , class_name: 'Member', foreign_key: 'sender_id'
end
class Member < ApplicationRecord
  has_many :receiver_records , class_name: 'MoneyRecord', foreign_key: 'receiver_records_id'
  has_many :sender_records   , class_name: 'MoneyRecord', foreign_key: 'sender_records_id'
end

できたこと/できなかったこと

rails consoleで

member_1 = Member.new(member_name: "hoge")
member_1.save
member_2 = Member.new(member_name: "fuga")
member_2.save

mr = MoneyRecord.new
mr.sender   = member_1
mr.receiver = member_2

でsender, receiverにMemberを割り当てることはできましたが、  
mr.save! を実行すると

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table: main.sender

というエラーが出てdbに登録できません。  
おそらくモデル内のアソシエーションの記述がまずいのだと思いますが、  
どのようにすればこの問題が解消するでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

結局あのあといろいろと調べた結果、
Railsが参照先のテーブルを解決できない場合はマイグレーションファイルに
table_to オプションを使用して明示的に教えてあげる必要があるということが分かりました。

詳しくはQiitaにまとめましたのでそちらをご覧ください↓
1つのモデルに別の1つのモデルを複数個持たせる方法[Rails5]

winterboumさん、ご回答ありがとうございました。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

関連の記述は問題ないように思えます。

no such table: main.sender というのがなんとも、、、

class MoneyRecord の定義は2行で全てですか?
出さなかった所に何か有るかも

あと migationかdb/schema.rbかをみせて下さい。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/09/20 23:11

    ご回答ありがとうございます。
    試しに簡易版を作成してrails consoleでデータを登録しようとしてみましたが、同様の `no such table` で登録できず、、、

    以下にmigrationファイルとschemaファイルを貼ります。

    ```create_money.rb
    class CreateMoney < ActiveRecord::Migration[5.2]
    def change
    create_table :money do |t|
    t.references :receiver, foreign_key: true
    t.references :sender, foreign_key: true

    t.timestamps
    end
    end
    end
    ```

    ```create_members.rb
    class CreateMembers < ActiveRecord::Migration[5.2]
    def change
    create_table :members do |t|
    t.string :name

    t.timestamps
    end
    end
    end
    ```

    ```db/schema.rb
    ActiveRecord::Schema.define(version: 2019_09_19_160323) do

    create_table "members", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    end

    create_table "money", force: :cascade do |t|
    t.integer "receiver_id"
    t.integer "sender_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["receiver_id"], name: "index_money_on_receiver_id"
    t.index ["sender_id"], name: "index_money_on_sender_id"
    end

    end
    ```

    ```member.rb
    class Member < ApplicationRecord
    has_many :sender_records, class_name: 'Money', foreign_key: 'sender_id'
    has_many :receiver_records, class_name: 'Money', foreign_key: 'receiver_id'
    end
    ```

    ```money.rb
    class Money < ApplicationRecord
    belongs_to :receiver, class_name: 'Member', foreign_key: 'receiver_id'
    belongs_to :sender, class_name: 'Member', foreign_key: 'sender_id'
    end
    ```

    キャンセル

  • 2019/09/21 06:04

    エラーメッセージで no such table: main.sender となる所は解せませんが、一つ問題が有るのは判りました。
    モデル MoneyRecord を定義してありますが、DBにそれに対応するtableがありません。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る