Tengo dos modelos y la asociación entre ellos es has_and_belongs_to_many . Necesito refactorizar el código ya que genera n + 1 consultas.
Problema: n+1 consultas
1. Tarea
class Task < ActiveRecord::Base has_and_belongs_to_many :user_groups end2. Grupo de usuarios
class UserGroup < ActiveRecord::Base has_and_belongs_to_many :tasks endRequisito:
Asignar tareas a grupos_de_usuarios
Código de controlador anterior:
task_ids.each do |task_id| find(task_id).update_attributes! user_group_ids: params[:user_group_ids], release_date: params[:release_date] endMi intento:
tasks = Task.where(id: task_ids) tasks.update_all(user_group_ids: params[:user_group_ids], release_date: params[:release_date])Error:
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: la columna "user_group_ids" de la relación "tareas" no existe
Consulta generada:
SQL (0.6ms) ACTUALIZAR "tareas" SET "user_group_ids" = 4, "release_date" = '2017-04-27 07:40:26.525357' DONDE "tareas"."deleted_at" ES NULO Y "tareas"."id" = 47394
Por favor, hágame saber cómo hacerlo con update_all
¿Por qué tuviste que crear el modelo UserGroup? Esa no es la forma en que usamos una relación habtm .
Y su modelo Task , en medio de todo, me confundió un poco. ¿Qué es lo que tiene que hacer? Sospecho que no tienes una relación habtm en Task .
Por el error que está recibiendo, es totalmente comprensible. No tiene un atributo (columna) llamado user_group_ids en la tabla de tasks . Y también, para una relación habtm , este atributo user_group_ids me parece mal escrito.
De todos modos, para una relación habtm , si su Usuario tiene muchos Grupos y un Grupo puede tener muchos Usuarios, está en el camino correcto, sin embargo, para Ruby on Rails hay dos formas de lograrlo.
Si no necesita administrar otros datos (atributos de relación) en la tabla de relaciones:
groups_users , en su caso. Rails buscará la tabla de relaciones habtm en orden alfabético. Si su relación groups_users contiene otros datos además de los ID de referencia del modelo, entonces es mejor que use una relación has_many :through .
En este caso, su tabla UserGroup (cuidado con la singularidad) contendrá los datos adicionales que necesita en la relación. Entonces declaras lo siguiente:
El modelo User habrá declarado: has_many :groups, through: :user_groups
Group habrá declarado: has_many :users, through: :user_groupsUserGroup de grupo de usuarios: belongs_to :user y belongs_to :group . Tenga cuidado de no indexar ninguno de ellos como único, base de datos o nivel de aplicación.Para obtener más detalles, consulte http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
¡Espero que obtengas tus resultados!
Su solución (sin causar un N+1) es activerecord-import
No puede asignar en masa la asociación usando update_all . update_all hace una sola consulta de ACTUALIZACIÓN, pero para la asociación en realidad necesita una consulta de INSERCIÓN para insertar los modelos asociados. Podría usar una gema como bulk_insert para insertar todos los objetos de unión con una consulta INSERT https://github.com/jamis/bulk_insert