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
. )