I have 2 Rails models: Book and Category, where a book belongs_to
a category, a category has_many
books.
The category name is shown in each book's page, and pages are cached.
If I change a category name (say, from 'Sci Fi' to 'Science Fiction'), then all corresponding book pages will be stale, and books need to be "touched" in order to trigger HTML regeneration.
It would seem to make sense to be able to do:
class Category << ActiveRecord::Base
has_many :books, touch: true
end
But the option is unavailable, I guess because the touch
mechanism would instantiate each object, which could result in a major performance hit for has_many
relationships.
To avoid that, I am using raw SQL as follows:
class Category << ActiveRecord::Base
has_many :books
after_update -> {
ActiveRecord::Base.connection.execute "UPDATE books SET updated_at='#{current_time_string}' WHERE category_id=#{id})"
}
end
Which is pretty terrible. Is there a better way?
The only difference between hasOne and belongsTo is where the foreign key column is located. Let's say you have two entities: User and an Account. In short hasOne and belongsTo are inverses of one another - if one record belongTo the other, the other hasOne of the first.
In rails touch is used to update the updated_at field for persisted objects. But if we pass other attributes as arguments, it will update those fields too along with updated_at . Even it will update non-date-time fields if passed as arguments.
A has_many association is similar to has_one , but indicates a one-to-many connection with another model. You'll often find this association on the "other side" of a belongs_to association. This association indicates that each instance of the model has zero or more instances of another model.
You can't use touch
on has_many
association, it works only with belongs_to
, that's a fact.
If I understand correctly what you want, the answers with touch:true
in the Book model won't work, because the Book object will not be updated when You change the Category model and the view will not regenerating.
So I think your solution is the best for that. (You can use also books.update_all(updated_at: Time.now)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With