【问题标题】:How to specify conditions on joined tables in rails如何在rails中的连接表上指定条件
【发布时间】:2012-01-27 13:17:33
【问题描述】:

我正在尝试在 Rails 中使用 ActiveRecord 进行查询,以指定连接表的某些条件。而且我似乎无法让它工作,即使我遵循这里的例子:

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

来自guides

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

我的数据库架构如下所示,其中包含表 scoressubmissionstasks

  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

【问题讨论】:

    标签: sql ruby-on-rails activerecord


    【解决方案1】:

    子句中的名称应该是复数来引用表名:

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

    【讨论】:

    • 事实上,根据发布的 Rails 指南 sn-p,joins 符号也应该如此。
    • @Chowlett,那是因为他们有一个多对多的关系,我只有一个一对一,has_one,而不是 has_many。这也是为什么我没有抓住我认为的表名的复数形式。
    【解决方案2】:

    子句名称应为复数以引用表名。

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

    如果 score 有很多提交,连接符号也应该是复数来引用分数和提交之间的关系。

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

    【讨论】:

      【解决方案3】:

      我觉得这更容易。

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

      【讨论】:

        【解决方案4】:

        警告:如果您使用的是非标准表名,上述操作将失败,如下所示:

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

        要解决此问题,请将(joined-model-class).table_name 作为where 哈希中的键:

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

        【讨论】:

          【解决方案5】:

          您的查询如下所示:

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

          您的#joins 是正确的,但:submission 应该是复数:

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

          【讨论】:

            猜你喜欢
            • 2015-07-20
            • 2010-11-14
            • 2012-08-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-07-25
            相关资源
            最近更新 更多