web-dev-qa-db-ja.com

railsで結合テーブルの条件を指定する方法

結合テーブルの条件を指定するActiveRecordでRailsでクエリを実行しようとしています。ここから例を実行しても、動作するようには見えません。 :

http://guides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-the-joined-tables

ガイド から:

Client.joins(:orders).where(:orders => {:created_at => time_range})

私のデータベーススキーマは、テーブルscoressubmissionsおよびtasksを使用して次のようになります。

  create_table "scores", :force => true do |t|
    t.integer  "value"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "scores", ["user_id"], :name => "index_scores_on_user_id"

  create_table "submissions", :force => true do |t|
    t.integer  "user_id"
    t.integer  "task_id"
    t.integer  "score_id"
    t.datetime "completed_at"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "submissions", ["score_id"], :name => "index_submissions_on_score_id"
  add_index "submissions", ["task_id"], :name => "index_submissions_on_task_id"
  add_index "submissions", ["user_id"], :name => "index_submissions_on_user_id"

  create_table "tasks", :force => true do |t|
    t.integer  "episode_id"
    t.integer  "score"
    t.string   "key"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

だから、特定のタスクに関連するすべての「スコア」を見つけることができるクエリを実行したいと思います。提出はタスクとスコアに属します。

クエリは次のようになります。

Score.joins(:submission).where(:submission => {:task_id => 1})

これにより、次の構文が生成されます。

SELECT "scores".* FROM "scores" INNER JOIN "submissions" ON "submissions"."score_id" = "scores"."id" WHERE "submission"."task_id" = 1

次のエラーが生成されます。

SQLite3::SQLException: no such column: submission.task_id

ただし、submission.task_id列があり、dbスキーマで確認できます。そして、私はこれを正常に行うことができます:

SELECT "submissions".* FROM "submissions" WHERE "submissions"."task_id" = 1
39
espenhogbakk

句の名前は、テーブル名を参照するために複数形にする必要があります。

Score.joins(:submission).where(:submissions => {:task_id => 1})
63
Nick

句名は、テーブル名を参照するために複数形にする必要があります。

Score.joins(:submission).where(submissions: { task_id: 1 })

スコアに多数の提出物がある場合は、スコアと提出物の関係を参照するために、結合記号も複数にする必要があります。

Score.joins(:submissions).where(submissions: { task_id: 1 })
7
leandrotk

警告:非標準のテーブル名を使用している場合、上記のように失敗します:

ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "submissions"

これを修正するには、(joined-model-class).table_namewhereハッシュのキーとして:

Score.joins(:submission).where(
  Submission.table_name => {task_id: 1}
)
4
Matt Hucke

これは簡単だと思います。

Score.joins(:submission).merge(Submission.where(task_id: 1))
4
thedanotto

クエリは次のようになります。

Score.joins(:submission).where(:submission => { :task_id => 1 })

きみの #joinsは正しいが、:submissionは複数形でなければなりません:

Score.joins(:submission).where(:submissions => { :task_id => 1 })
1
jmjm