Repository navigation
Set inverse asoociation for cache_has_many without :embed => true - #360
roccoblues wants to merge 14 commits into
Conversation
|
|
||
| #### 1.0.0 Unreleased | ||
|
|
||
| - Set inverse asoociation for cache_has_many without `:embed => true` |
There was a problem hiding this comment.
I would say it is for an "id embedded cach_has_many associations" rather than saying what it isn't for.
dylanahsmith
left a comment
There was a problem hiding this comment.
Looks like prefetch_one_association also needs to be changed so that the inverse cached association is also set when the association is batch loaded (e.g. through using the :includes option on fetch).
| options[:records_variable_name] = "cached_#{association}" | ||
| options[:prepopulate_method_name] = "prepopulate_fetched_#{association}" | ||
|
|
||
| inverse_name = options[:association_reflection].inverse_of.try(:name) |
There was a problem hiding this comment.
Prefer try! over try, since the latter also does a respond_to? check that can hide bugs.
| @#{options[:records_variable_name]} ||= #{options[:association_reflection].class_name}.fetch_multi(#{options[:cached_ids_name]}) | ||
| @#{options[:records_variable_name]} ||= begin | ||
| #{options[:association_reflection].class_name}.fetch_multi(#{options[:cached_ids_name]}).map do |record| | ||
| record.send('#{inverse_name}=', self) if #{inverse_name.present?} |
There was a problem hiding this comment.
We don't want to set the association itself, since putting records loaded from the cache into an active record association would make it easier to unintentionally persist that data to the database, which could persist cache corruption. Instead, we want to make sure they use the cached accessor to access it. Can you re-use set_inverse_of_cached_association to do it the same way as embedded cached associations?
| end | ||
|
|
||
| def test_fetch_should_setup_association_for_cache_has_many | ||
| Item.cache_has_many :associated_records |
There was a problem hiding this comment.
Explicitly use the :embed => :ids option for clarity
|
|
||
| records = item.fetch_associated_records | ||
| records.each do |r| | ||
| assert_equal item.object_id, r.item.object_id |
There was a problem hiding this comment.
You should need to use r.fetch_item.
|
|
||
| item = Item.find_by_id(@item.id) | ||
|
|
||
| records = item.fetch_associated_records |
There was a problem hiding this comment.
This will always just delegate to the active record association, since item wasn't fetched from the cache.
| @@ -0,0 +1,53 @@ | |||
| require "test_helper" | |||
|
|
|||
| class InverseOfTest < IdentityCache::TestCase | |||
There was a problem hiding this comment.
Aren't there already tests for setting the inverse cached association? If there are already tests in denormalized_has_many_test.rb, denormalized_has_one_test.rb and normalized_belongs_to_test.rb then we just need tests for this behaviour in normalized_has_many_test.rb
There was a problem hiding this comment.
No really, only this: https://github.com/Shopify/identity_cache/blob/master/test/denormalized_has_many_test.rb#L105 and I'm not sure what it tests.
| item = Item.find_by_id(@item.id) | ||
|
|
||
| record = item.fetch_associated | ||
| assert_equal item.object_id, record.item.object_id |
There was a problem hiding this comment.
This will always just delegate to the active record association, since item wasn't fetched from the cache and this is an embedded cached association.
| end | ||
|
|
||
| def test_fetch_should_setup_association_for_cache_belongs_to | ||
| Item.cache_belongs_to :associated |
There was a problem hiding this comment.
This seems like it should raise, since the model doesn't even have a belongs_to :associated association, nor does the table have an associated_id column on the items table. I think this must be actually using the has_one association.
|
|
||
| #### 1.0.0 Unreleased | ||
|
|
||
| - Set inverse asoociation for cache_has_many without `:embed => true` |
There was a problem hiding this comment.
I would say it is for an "id embedded cach_has_many associations" rather than saying what it isn't for.
| def test_fetch_should_setup_association_for_cache_has_many | ||
| Item.cache_has_many :associated_records | ||
|
|
||
| item = Item.find_by_id(@item.id) |
There was a problem hiding this comment.
Use find when you always expect it to return a record.
|
@dylanahsmith I have the feeling we've been talking about different things. Can you have a look at the code in the related issue again? Here's what I meant in pseudo-code: I just found that you even have a test that this should explicitly not happen: https://github.com/Shopify/identity_cache/blob/master/test/denormalized_has_many_test.rb#L124 ? Did you instead think about this? |
In that case it is using the active record association |
|
Ok, I think I got it now. Please check again. |
|
the default branch was renamed from |
Fixes #357