tag rails link_to content_tag ruby-on-rails ruby activerecord

ruby-on-rails - content_tag link_to rails



Encontrar nil tiene_una asociaciĆ³n en donde consulta (3)

Encontré otras dos formas de hacer esto:

Item.includes(:purchase).references(:purchase).where("purchases.id IS NULL") Item.includes(:purchase).where(purchases: { id: nil })

Técnicamente, el primer ejemplo funciona sin la cláusula ''referencias'', pero Rails 4 escupe advertencias de obsoles sin él.

Esta puede ser una pregunta simple, pero parece que me estoy tirando de los pelos para encontrar una solución elegante aquí. Tengo dos clases de modelo de ActiveRecord, con una asociación has_one y belongs_to entre ellas:

class Item < ActiveRecord::Base has_one :purchase end class Purchase < ActiveRecord::Base belongs_to :item end

Estoy buscando una forma elegante de encontrar todos los objetos Item, que no tengan ningún objeto de compra asociado a ellos, idealmente sin recurrir a tener un booleano is_purchased o un atributo similar en el Item.

En este momento tengo:

purchases = Purchase.all Item.where(''id not in (?)'', purchases.map(&:item_id))

Lo cual funciona, pero me parece ineficiente, ya que está realizando dos consultas (y las compras podrían ser un conjunto de registros masivos).

Running Rails 3.1.0


Es una tarea bastante común, SQL OUTER JOIN generalmente funciona bien para ello. Eche un vistazo here , por ejemplo.

En tu caso intenta usar algo como

not_purchased_items = Item.joins("LEFT OUTER JOIN purchases ON purchases.item_id = items.id").where("purchases.id IS null")


Una versión más concisa de la solución @dimuch es usar el método left_outer_joins introducido en Rails 5:

Item.left_outer_joins(:purchase).where(purchases: {id: nil})

Tenga en cuenta que en la llamada left_outer_joins :purchase es singular (es el nombre del método creado por la declaración has_one ), y en la cláusula where :purchases es plural (aquí está el nombre de la tabla a la que pertenece el campo id . )