Dat Tran
Dat Tran

Reputation: 159

get association's association with ecto

I have 4 table, which is:

Category -> sub1 -> sub2 -> product

the tables are defined

Category

-name
-id
-description

sub1

-id
-category_id
-name
-description

sub2

-id
-sub1_id
-name
-description

product

-id
-sub2_id
-name
-description
-color

i have my schema defined as:

category.ex

schema "categories" do
    field :name, :string

    timestamps()
  end

sub1.ex

 schema "sub1" do
    field :name, :string
    belongs_to :category, App.Category
    timestamps()
  end

sub2.ex

 schema "sub2" do
        field :name, :string
        belongs_to :sub1, App.Sub1
        timestamps()
      end

product.ex

  schema "product" do
            field :name, :string
            belongs_to :sub2, App.Sub2
            timestamps()
          end

in my controller i tried preload sub2 and sub1 as

products = Product
                |> Repo.all
                |> Repo.preload(:sub2)
                |> Repo.preload(sub2: :sub1)

and it worked. However when i try to preload category as

 products = Product
                    |> Repo.all
                    |> Repo.preload(:sub2)
                    |> Repo.preload(sub2: :sub1)
                    |> Repo.preload(sub1: :category)

i got error saying product doesn't have association with sub1. Is there a way to make this to work? Ultimately i want to be able to do

product.sub2.sub1.category.name

in my template and it would output the name of the category

Upvotes: 0

Views: 329

Answers (1)

bschaeffer
bschaeffer

Reputation: 2904

Have you tried Repo.preload(sub2: [sub1: [:category]])

The error comes from the fact the last preload in

Repo.all(Product) 
|> Repo.preload(sub2: sub1) 
|> Repo.preload(sub1: :category)

actually goes back to the original query, so it's essentially

Repo.all(Product) 
|> Repo.preload(sub1: :category)

which is invalid based on your schema.

Upvotes: 0

Related Questions