tutorial rails quimica que ejemplos descargar curso caracteristicas ruby-on-rails associations scopes

ruby on rails - quimica - ¿Cómo paso un argumento a un ámbito de asociación has_many en Rails 4?



ruby on rails que es (3)

La forma es definir un selector adicional extendido para el alcance de has_many :

class Customer < ActiveRecord::Base has_many :orders do def by_account(account) # use `self` here to access to current `Customer` record where(:account_id => account.id) end end end customers.orders.by_account(account)

El enfoque se describe en el encabezado de Association Extension de la Association página de la Association Rieles.

Para acceder al registro del Customer en el método anidado, solo puede acceder al objeto self , debe tener el valor del registro del Customer actual.

Sinse of rails (aproximadamente 5.1), puede combinar el alcance de los modelos con el otro modelo tiene muchos alcances del mismo tipo, por ejemplo, puede escribir el mismo código de la siguiente manera en los dos modelos:

class Customer < ApplicationRecord has_many :orders end class Order < ApplicationRecord scope :by_account, ->(account) { where(account_id: account.id) } end customers.orders.by_account(account)

Rails 4 te permite ver una relación has_many como esta:

class Customer < ActiveRecord::Base has_many :orders, -> { where processed: true } end

Así que en cualquier momento que hagas customer.orders , solo recibirás pedidos procesados.

¿Pero qué pasa si necesito hacer que la condición de where dinámica? ¿Cómo puedo pasar un argumento al alcance lambda?

Por ejemplo, solo quiero que se muestren los pedidos de la cuenta en la que el cliente está conectado actualmente en un entorno de múltiples inquilinos.

Esto es lo que tengo:

class Customer < ActiveRecord::Base has_many :orders, (account) { where(:account_id => account.id) } end

Pero, ¿cómo, en mi controlador o vista, paso la cuenta correcta? Con el código de arriba en su lugar cuando lo hago:

customers.orders

Recibo todos los pedidos por cuenta con un ID de 1, aparentemente arbitrariamente.


Pasas en una instancia de la clase que has definido. En su caso, pasaría a un cliente y luego obtendría la cuenta.

De la API Association

Accediendo al objeto propietario

A veces es útil tener acceso al objeto propietario al crear la consulta. El propietario se pasa como un parámetro al bloque. Por ejemplo, la siguiente asociación encontraría todos los eventos que ocurren en el cumpleaños del usuario:

class User < ActiveRecord::Base has_many :birthday_events, ->(user) { where starts_on: user.birthday }, class_name: ''Event'' end

En tu ejemplo sería:

class Customer < ActiveRecord::Base has_many :orders, ->(customer) { where(account_id: customer.account.id) } end


Sé que esto es antiguo, pero como no se aceptó ninguna respuesta, pensé que agregar mis puntos de vista sobre el tema no perjudicaría a nadie.

El problema es que siempre que pase un alcance a una relación has_many , pasar la instancia de la clase propietaria como un argumento no solo es una posibilidad, sino que es la única posibilidad de pasar un argumento. Quiero decir, no se le permite pasar más argumentos, y esta siempre será la instancia de la clase propietaria.

Así que @RobSobers, cuando tu

"obtener todos los pedidos por cuenta con un id de 1, aparentemente arbitrariamente".

no es arbitrario, usted recibe todos los pedidos con la id del customer que llamó la relación. Supongo que tu código era algo así como

Customer.first.orders(@some_account_which_is_ignored_anyway)

Parece que la relación has_many no estaba destinada a aceptar argumentos.

Personalmente, prefiero la solución de @ МалъСкрылевъ.