2012-01-27 14 views
24

Estoy intentando hacer una consulta en Rails con ActiveRecord que especifica alguna condición en una tabla unida. Y me parece que no puede conseguir que funcione, a pesar de que siguen a los ejemplos de aquí:Cómo especificar condiciones en tablas unidas en rieles

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

De la guía de guides.rubyonrails.org:

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

mi esquema de base se parece a esto, con una puntuación, de la sumisión y de la tarea tablas:

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 

Por eso quiero hacer una consulta donde puedo encontrar todas las "puntuaciones" que tienen una relación con una tarea spesific. La presentación pertenece a tareas y puntajes.

Mi consulta ahora se ve así:

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

Esto genera la siguiente sintaxis:

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

que genera el siguiente error:

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

Pero hay una columna submission.task_id , que puedes ver en el esquema db. Y puedo hacer esto con éxito:

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

Respuesta

44

El nombre en la cláusula debe ser plural para hacer referencia al nombre de la tabla:

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

De hecho, de acuerdo con el fragmento de guía de Rails publicado, también debería aparecer el símbolo 'join'. – Chowlett

+1

¡Es totalmente correcto! Acabo de descubrir eso por mi cuenta. Maldito. – espenhogbakk

+0

@Chowlett, es porque tienen una relación Muchos a Muchos, solo tengo uno a uno, has_one, instad de has_many. Esa es también la razón por la que no entendí el plural en referencia al nombre de la tabla, creo. – espenhogbakk

0

Su consulta se ve así

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

Sus #joins es correcto, pero tu #where: presentación debe ser plural.

3

Advertencia: si utiliza nombres de tabla no estándar, lo anterior fallará.

ActiveRecord :: StatementInvalid: PG :: UndefinedTable: ERROR: falta cláusula FROM de entrada para la tabla "presentaciones"

Para solucionar este problema, ponen (joined-model-class).table_name como una llave en la almohadilla donde:

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

4

El nombre de la cláusula debe ser plural para hacer referencia al nombre de la tabla.

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

Si la puntuación tiene muchos envíos, el símbolo de uniones también debe ser plural para hacer referencia a la relación entre Puntuación y Presentación.

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

Encuentro que esto es más fácil.

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