Skip to content

Instantly share code, notes, and snippets.

@jesuslerma
Last active August 29, 2015 14:22
Show Gist options
  • Save jesuslerma/934f33646de1f6042122 to your computer and use it in GitHub Desktop.
Save jesuslerma/934f33646de1f6042122 to your computer and use it in GitHub Desktop.
Pequeña explicación de como funcionan los scopes
#No entiendo bien el problema. Lo de los scopes como esta encadenado lo puedes mandar a llamar las veces que sea
#Yo veo los scopes como una forma mas de definir métodos
#Pero un poco más limpia
#Tal vez el método que definiste estaba mal y pore so se tardaba, pero puedes encadenar varios scopes. De hecho en el modelo de #facturas encadeno varias veces los scopes
#Esto se usa más que nada cuando haces una busqueda con varios parametros
#y los parametros son opcionales, por ejemplo si queremos buscar los ingresos de un año
#definimos el scope para sacar ingresos, y otro para sacar el año
scope :ingresos, ->(rfc) { where(rfc_em: rfc, is_nomina: false)}
scope :in_year, ->(y) { where("extract(year from fecha_expedicion) = ?", y)}
#En ambos scopes, lo interesante es que regresan el elemento where
#Ahí es donde sucede el encadenamiento, por que lo que regresa el método es una funcion y no un resultado
#Por ejemplo, tu puedes hacer esto
Factura.ingresos(rfc).in_year(2015)
#o puedes hacer esto
facturas = Factura.ingresos(rfc)
facturas = facturas.in_year(2015)
#Eso se llama encadenamiento de métodos
#La ventaja aquí es que la query se ejecutará cuando ruby detecte que has terminado de encadenar o que mandes a llamar un método que #necesite llamar al método
#Cuando haces esto
facturas = Factura.ingresos(rfc)
facturas = facturas.in_year(2015)
#Es como si estuvieras haciendo esto:
Factura.ingresos(rfc).in_year(2015)
#O bien esto tambien
Factura.where(rfc_em: rfc, is_nomina: false).where("extract(year from fecha_expedicion) = ?", y) (edited)
#entonces tu puedes tener un método que tenga parametros opcionales, por ejemplo el que definimos en el modelo factura.rb
def self.get_clientes(rfc,size, options)
facturas = Factura.ingresos rfc
if options.has_key?(:year)
facturas = facturas.in_year options[:year]
if options.has_key?(:month)
facturas = facturas.in_month options[:month]
end
end
facturas.group_by{|g| g.nombre_receptor }
.map{|r| {r[0] => r[1].map{|n| n.calcSubTotal}.sum}}
.sort_by{|r| -r.first[1]}
.first(size)
#.first(size)
#.sort_by{|r| -r.first[1]}
end
#y la query se va a ejecturar hasta que llegas a la línea en donde mandas a llamar el group_by
#Es importante darse cuenta de que tu puedes definir los scopes o los métodos, por lo tanto esto:
scope :ingresos, ->(rfc) { where(rfc_em: rfc, is_nomina: false)}
scope :in_year, ->(y) { where("extract(year from fecha_expedicion) = ?", y)}
#Es lo mismo que esto:
def ingresos(rfc)
where(rfc_em: rfc, is_nomina: false)
end
def in_year(y)
where("extract(year from fecha_expedicion) = ?", y)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment