¿Qué hace send () hacer en Ruby?

¿Puede alguien decirme qué

send("#{Model.find...}") 

es y hace?

send envía un mensaje a una instancia de objeto y sus ancestros en la jerarquía de clases hasta que algún método reaccione (porque su nombre coincide con el primer argumento).

Prácticamente hablando, esas líneas son equivalentes:

 1.send '+', 2 1.+(2) 1 + 2 

Tenga en cuenta que el send omite las comprobaciones de visibilidad, de modo que también puede llamar a métodos privados (útil para pruebas unitarias).


Si realmente no hay una variable antes de enviar, eso significa que se utiliza el objeto global:

 send :to_s # "main" send :class # Object 

send es un método de ruby ​​(sin Rails) que permite invocar otro método por nombre.

De la documentación

  class Klass def hello(*args) "Hello " + args.join(' ') end end k = Klass.new k.send :hello, "gentle", "readers" #=> "Hello gentle readers" 

http://corelib.rubyonrails.org/classes/Object.html#M001077

Una de las características más útiles que creo que con el método .send es que puede invocar dinámicamente el método. Esto puede ahorrarle mucho tipeo. Uno de los usos más populares del método .send es asignar atributos dinámicamente. Por ejemplo:

 class Car attr_accessor :make, :model, :year end 

Para asignar atributos regularmente uno necesitaría

 c = Car.new c.make="Honda" c.model="CRV" c.year="2014" 

O usando el método .send:

 c.send("make=", "Honda") c.send("model=", "CRV") c.send("year=","2014") 

Pero todo puede ser reemplazado con lo siguiente:

Asumiendo que su aplicación Rails necesita asignar atributos a su clase de auto a partir de la entrada del usuario, puede hacer

 c = Car.new() params.each do |key, value| c.send("#{key}=", value) end 

Otro ejemplo, similar a https://stackoverflow.com/a/26193804/1897857 de Antonio Jha

es si necesita leer atributos en un objeto.

Por ejemplo, si tiene una matriz de cadenas, si intenta recorrerlas y llamarlas a su objeto, no funcionará.

 atts = ['name', 'description'] @project = Project.first atts.each do |a| puts @project.a end # => NoMethodError: undefined method `a' 

Sin embargo, puede send las cadenas al objeto:

 atts = ['name', 'description'] @project = Project.first atts.each do |a| puts @project.send(a) end # => Vandalay Project # => A very important project 

Otro caso de uso para las vistas:

  <%= link_to send("first_part_of_path_{some_dynamic_parameters}_end_path", attr1, attr2), .... %> 

Permitir escribir una vista escalable que trabaje con todo tipo de objetos con:

  render 'your_view_path', object: "my_object"