timpone
timpone

Reputation: 19929

Rails - How to refresh an association after a save

I have a category with a list of items. The items have a position and the category has a relationship has_many :items, :order => "position". When a user updates a position value, I want to see its position. My position is a float to allow moving between rounded numbers.

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

The above works but it seems really verbose. Is there a way for me to tell on item save that the category relationship needs to be refreshed since the order could be changed?

Upvotes: 35

Views: 37841

Answers (3)

Benjamin Atkin
Benjamin Atkin

Reputation: 14715

For single-item associations:

book.reload_author

For other associations:

author.books.reload

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


In older versions of rails, before Rails 5, you could pass true to an association method as the first parameter to make it reload: author.books(true).

Upvotes: 76

robertoplancarte
robertoplancarte

Reputation: 1171

Rails 4 will update your has_many/belongs_to associated objects for you when they change, but it will not re-run the query which means that even though the items in the category.items will be updated they will not be in order. Depending on the size of your tables you may want to use ruby to order the result or use category.reload to get them in order.

See the RailsGuides at http://guides.rubyonrails.org/association_basics.html and look for inverse_of

Upvotes: 6

Intrepidd
Intrepidd

Reputation: 20868

You can use item.reload that will refetch the model from the database and next time you call an association, it will refetch it.

Upvotes: 37

Related Questions