On Friday, April 7, 2017 at 1:14:39 AM UTC-7, Andrew Burleson wrote:
>
> Hi Jeremy,
>
> I noticed something today, and I'm wondering if maybe I'm misunderstanding
> it...
>
> I've got an association like this:
>
> class Book < Sequel::Model
> one_to_many :chapters
>
>
> # has attribute "title"
> end
>
>
> class Chapter < Sequel::Model
> many_to_one :book
>
>
> # also has attribute title
> def full_title
> book.title + title
> end
> end
>
>
> This is a somewhat simplified example but, you get the idea.
>
> What I found was that if I loaded a book, for example:
>
> book = Book.with_pk! 123
>
> Then I loop through its chapters:
>
> book.chapters.all.each{|c| puts c.full_title }
>
> That I'm getting a query for every chapter that looks like this:
>
> SELECT * FROM "books" WHERE ("id" = 123) ORDER BY "id" LIMIT 1
>
> Hence, my conclusion that when a book loads its chapters via
> `book.chapters` or `book.chapters.all` it does not pass a reference to
> itself into the children, and each child has to look up the parent in order
> to use the reference.
>
> On a whim I tried doing `Book.where(id:
> 123).eager(:chapters).first.chapters...` to see if that would change
> things, but I still see an N+1 in the query logs.
>
> So, am I interpreting that correctly? And if so, is there a mechanism by
> which I can load the children of a model and pass them a reference to the
> parent so they don't query for it?
>
First, this should be handled correctly by default, assuming the
association can determine the correct reciprocal association. If not, you
may have to specify the reciprocal association:
Book.many_to_one :chapters, :reciprocal=>:book
Chapter.many_to_one :book, :reciprocal=>:chapters
With the example you gave, it should determine the reciprocal association
correctly. Can you produce a minimal self contained example where it
cannot?
If this was an issue with loading associated records, you could use the
tactical_eager_loading plugin, which handles this natively, or you could do:
book.chapters{|ds| ds.eager(:book)}
Thanks,
Jeremy
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.