Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-level Imports #231

Closed
allenwlee opened this issue Feb 8, 2016 · 2 comments
Closed

Multi-level Imports #231

allenwlee opened this issue Feb 8, 2016 · 2 comments

Comments

@allenwlee
Copy link

The README strongly suggests that we can import multi-level objects, e.g.:

Say you had a schema like this:

Publishers have Books
Books have Reviews
and you wanted to bulk insert 100 new publishers with 10K books and 3 reviews per book. This library will follow the associations down and generate only 3 SQL insert statements - one for the publishers, one for the books, and one for the reviews.

where search has_many :tiers through: :searches_tiers
I've tried the following:

s=Search.new(name: 'Foo')
s.tiers << Tier.new(name: 'Bar')
Search.import [s]

search gets imported
tier does not

should this work?

Also, pull request #104 , although mainly about returning ids in Postgres, has a subconversation about multi-level importing, which was implemented in this fork by @GoodMeasuresLLC, now stale. Can someone please clarify whether multi-level import is available or not?

@johnnaegle
Copy link
Contributor

Multilevel import does work, however, it is only implemented for autosave associations (I believe there is an issue or PR to change that behavior) and you need to import with :recursive => true

The tests have an example:

Topic.import new_topics, :recursive => true

I think if you change your has_many :tiers association, and maybe the :searches_tiers to be autosave true and add the recursive option to the import, you'll get tiers imported.

@allenwlee
Copy link
Author

Thanks for your response @johnnaegle . You were right about the recursive: true, but I also needed to add inverse_of: to my model:

For Rails 4.2.0:
Models

class Search
  has_many :company_tiers_searches, inverse_of: :search, dependent: :destroy
end

class CompanyTiersSearch
  belongs_to :search
  validates_presence_of :search
end

then

s=Search.new(period_start: DateTime.now); 
s.company_tiers_searches.build(company_role_id: 4, company_tier_id: 1);
Search.import [s], recursive: true

successfully resulted in
#<struct ActiveRecord::Import::Result failed_instances=[], num_inserts=1, ids=["6912"]>

Note also that you will need to use validates_presence_of :search, rather than validating search_id, since you will be creating both Search and CompanyTiersSearch simultaneously and so there will be no extant search_id before save.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants