2012-10-01 27 views
16

Tengo una categoría con una lista de elementos. Los artículos tienen una posición y la categoría tiene una relación has_many: items,: order => "position". Cuando un usuario actualiza un valor de posición, quiero ver su posición. Mi posición es un flotador para permitir el movimiento entre números redondeados.rails - cómo actualizar una asociación después de guardar

pos=item.category.items.map(&:id) 
current_position=pos.index(id.to_i) 
item.save # want to refresh the relationship here 
pos_new=item.categoty.items.map(&:id) 
# grabbing this since just accessing item isn't updated if positioning has changed 
item_new=Item.find(id) 
pos_new=item_new.category.items.map(&:id) 
new_position=pos_new.index(id) 
if current_position!=new_position 
    is_moved=true # sent back in JSON to propagate a dynamic change. 
end 

Lo anterior funciona pero parece muy detallado. ¿Hay alguna manera de decir en el artículo guardado que la relación de categoría debe actualizarse ya que el pedido podría cambiarse?

Respuesta

25

Puede usar item.reload que recuperará el modelo de la base de datos y la próxima vez que llame a una asociación, lo volverá a buscar.

4

Rails 4 actualizará sus objetos asociados has_many/belongs_to cuando cambien, pero no volverá a ejecutar la consulta, lo que significa que aunque los elementos en la categoría.artículos se actualizarán, no estarán en orden . Dependiendo del tamaño de sus tablas, puede usar ruby ​​para ordenar el resultado o usar category.reload para ordenarlas.

Ver las RailsGuides en http://guides.rubyonrails.org/association_basics.html y buscar inverse_of

32

Para las asociaciones un solo tema:

book.reload_author 

Para otras asociaciones:

author.books.reload 

http://guides.rubyonrails.org/association_basics.html#controlling-caching


En las versiones anteriores de los rieles, antes de Rails 5, puede pasar true a un método de asociación como el primer parámetro para que se vuelva a cargar: author.books(true).

+2

¿Quién todavía viene a esta respuesta de la búsqueda (como acabo de hacer): este comportamiento ya no es compatible con los rieles. Obtienes una advertencia de desaprobación. La nueva forma de recolección es usar el método 'reload' en el proxy de recopilación. – klaustopher

+0

@klaustopher Gracias. Actualizado mi respuesta. –

+1

"ADVERTENCIA DE DEPRESIÓN: Pasar un argumento para forzar a una asociación a recargarse ahora está en desuso y se eliminará en Rails 5.1. Llame a' reload' en el objeto principal en su lugar. (Llamado desde

en (pry): 2) " – Dorian

Cuestiones relacionadas